So, I have the following function:
public Sprite ReadSpriteFromFile(immutable(char)[] filename) { //Reads a sprite in my made up .spr format(trash, why does this even exist)
ubyte[] ftext;
Color[] colors;
Point[][] points;
import std.file;
import std.stdio;
ftext = cast(ubyte[])read(filename);
foreach(i;0 .. cast(uint)ftext.length) { //Parse the file...
long main;
short exp;
uint x = 0;
++colors.length;
++points.length;
colors[x].r = ftext[i]; //Set r color...
++i;
colors[x].g = ftext[i];
++i;
colors[x].b = ftext[i];
++i;
ubyte tempcolor = ftext[i];
++i;
long temp;
writeln(tempcolor); //For this matter, the program correctly reports tempcolor as 1...
for(ubyte j = 0;j < tempcolor; j++ /*trying ++j has same effect*/ ) { //tempcolor is 1, yet this sloop gets executed twice...
writeln();
posfunc(ftext, main, exp, temp, i, j, points , x); //Orignally foreach loop, but switching to for loop has same effect...
}
}
return Sprite(colors, points);
}
Here is the rest of the source:
/*sprite.d by Ruby The Roobster*/
/*Version 0.3.5 Release*/
/*Last Update: 08/23/2021*/
/*Module for sprites in the D Programming Language 2.0*/
module dutils.sprite;
import skeleton : Point;
version(USE_BUILT_IN_SPRITES) { //Use built in sprites(garbage .spr format coded by me, that still needs an editor: Editor using GtKD for .spr comes out later this year, if I can get myself to do it)...
public struct Color {
ubyte r = 0;
ubyte g = 0;
ubyte b = 0;
void opAssign(Color rhs) {
this.r = rhs.r;
this.g = rhs.g;
this.b = rhs.b;
}
}
public struct Sprite {
Color[] colors;
Point[][] points;
invariant() {
assert(colors.length == points.length, "Assertion failure: Sprite.colors.length and Sprite.points.length must always be equal...");
}
void opAssign(Sprite rhs) {
this.colors.length = rhs.colors.length;
this.points.length = rhs.points.length;
foreach(i;0 .. this.colors.length) {
this.colors[i] = rhs.colors[i];
}
foreach(i;0 .. this.points.length) {
this.points[i].length = rhs.points[i].length;
foreach(j;0 .. this.points[i].length) {
this.points[i][j] = rhs.points[i][j];
}
}
}
package void ChangeLengths(uint c) { //Change both lengths so invariant doesn't get triggered...
this.colors.length = c;
this.points.length = c;
}
}
//ReadSpriteFromFile was here...
package void posfunc(const ubyte[] ftext, ref long main, ref short exp, ref long temp, ref uint i, const ubyte j, ref Point[][] points, ref uint x) {
++points[x].length;
import std.stdio;
writeln(__LINE__);
foreach(z;0 .. 3) {
short shift = 56;
main = ftext[i];
main <<= shift;
++i;
shift -= 8;
while(shift >= 0) {
writeln(shift);
writeln(i);
temp = ftext[i];
main = (main <= (-0)) ? (main - temp) : (main + temp);
++i;
shift -= 8;
}
exp = ftext[i];
exp <<= 8;
++i;
exp += ftext[i];
if(i+1 == ftext.length) {
}
else {
++i;
}
switch(z) {
case 0:
points[x][j].x = (main * 10^^exp);
break;
case 1:
points[x][j].y = (main * 10^^exp);
break;
case 2:
points[x][j].z = (main * 10^^exp);
break;
default:
assert(false); //bruh...
}
}
}
}
version(USE_OTHER_SPRITE) { //If the user wants to work with sprites their own way...
public alias Sprite = uint function();
}
version(USE_FILE_SPRITE) { //If the user wants to read the sprites from a file and do it that way...
public alias Sprite = wchar[];
}
skeleton.d source:
/*skeleton.d by Ruby The Roobster*/
/*Version 1.0 Release*/
/*Module for representing skeletons in the D Programming Language 2.0*/
public struct Point { //Point structure...
real x;
real y;
real z;
void opAssign(Point rhs) {
this.x = rhs.x;
this.y = rhs.y;
this.z = rhs.z;
}
void opOpAssign(string op)(Point rhs) {
mixin("this.x " ~ op ~ "= rhs.x;");
mixin("this.y " ~ op ~ "= rhs.y;");
mixin("this.z " ~ op ~ "= rhs.z;");
}
}
public struct Face { //Face(of a 3D shape) structure...
Line[] lines;
Point center;
void opAssign(Face rhs) {
this.lines.length = rhs.lines.length;
foreach(i;0 .. this.lines.length) {
this.lines[i] = rhs.lines[i];
}
}
}
public struct Skeleton { //Skeleton of a 3D structure...
Face[] faces;
Point center;
void opAssign(Skeleton rhs) {
this.faces.length = rhs.faces.length;
foreach(i;0 .. this.faces.length) {
this.faces[i] = rhs.faces[i];
}
this.center = rhs.center;
}
}
public struct Line { //Line struct...
Point[] mid_points;
Point start;
Point stop;
void opAssign(Line rhs) {
this.start = rhs.start;
this.stop = rhs.stop;
this.mid_points.length = rhs.mid_points.length;
foreach(i;0 .. this.mid_points.length) {
this.mid_points[i] = rhs.mid_points[i];
}
}
}
Here is my test program for these:
//This file is called nid.d
import dutils.sprite;
import std.stdio;
void main() {
Sprite sprite = ReadSpriteFromFile("abc.txt");
writeln(sprite);
}
abc.txt in hexadecimal:
00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 01
Compiler Version: DMD 2.097.2
Command line: dmd nid.d sprite.d skeleton.d -version=USE_BUILT_IN_SPRITES
Sorry for this being long, but whole source files were provided for clarity. Why the heck is the loop being executed twice(check output for blank lines).
Also, if this is somehow relevant, I am on Windows 10 20H1 build 19043.1237.