Building a custom .dll file to use with RPG Maker...

Started by Heretic86, June 03, 2016, 05:55:07 pm

Previous topic - Next topic

Heretic86

June 22, 2016, 05:37:11 am #20 Last Edit: June 22, 2016, 07:13:51 pm by Heretic86
Yay!  I got garbage to be displayed, then crash!  Well, at least I got somewhere...  :facepalm:

--

Okay, source code so far.  It has some nasty problems tho.

dllmain.cpp
Spoiler: ShowHide
#include <cstdlib>
#include <ctime>
#include <ctype.h>
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <windows.h>

typedef union {
unsigned int pixel;
struct {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
};
} RGSSRGBA;

typedef struct {
DWORD flags;
DWORD class_type;
void(*dmark) (void*);
void(*dfree) (void*);
double *data; //red is index 1, green is index 2, blue 3, alpha 0
} RGSSCOLOR;

typedef struct {
DWORD unk1;
DWORD unk2;
BITMAPINFOHEADER *infoheader;
RGSSRGBA *firstRow;
RGSSRGBA *lastRow;
} RGSSBMINFO;

typedef struct {
DWORD unk1;
DWORD unk2;
RGSSBMINFO *bminfo;
} BITMAPSTRUCT;

typedef struct {
DWORD flags;
DWORD class_type;
void(*dmark) (void*);
void(*dfree) (void*);
BITMAPSTRUCT *bm;
} RGSSBITMAP;

# define M_PI           3.14159265358979323846  /* pi */

//===============================================================================
// * RotateRGSSBitmap
//  - Rotates Bitmaps in Game Memory
//        src_object : Object ID of RPG::Bitmap (bmp.object_id)
//     canvas_object : Object ID of Canvas to be drawn to - RPG::Bitmap
//             angle : Angle to rotate the Bitmap to in Degrees
//           showMsg : send a 1 to this Arg for a MessageBox
//===============================================================================
// Definately a work in progress.

extern "C" _declspec (dllexport) int RotateRGSSBitmap(unsigned long src_object, unsigned long canvas_object, float *pAngle, int showMsg = 0)
{
  // Get the Pointers to both Bitmaps for the Light Source and Canvas object to draw on
RGSSBMINFO *lightSrc = ((RGSSBITMAP*)(src_object << 1))->bm->bminfo;
RGSSBMINFO *lightCanvas = ((RGSSBITMAP*)(canvas_object << 1))->bm->bminfo;
// Quit processing if there is no Light Source RGSS Bitmap
if (!lightSrc || !lightCanvas) return 0;
// Get the angle value from packed pointer in Arg
double angle = pAngle[0];
// RGSS specific local variables used to transfer from Source to Canvas
RGSSRGBA *sourceData, *canvasData;
// Local Variables for determining rotation
int x, y, widthSrc, heightSrc, widthCanvas, heightCanvas;
// Width and Height of Light Source and Canvas RGSS Bitmaps
widthSrc = lightSrc->infoheader->biWidth;
heightSrc = lightSrc->infoheader->biHeight;
widthCanvas = lightCanvas->infoheader->biWidth;
heightCanvas = lightCanvas->infoheader->biHeight;
// Use Center of Canvas as center of rotation
float cX = (float)widthCanvas / 2;
float cY = (float)heightCanvas / 2;

// Change the angle in Degrees to Radians
double radianAngle = (M_PI * angle) / 180;
// Determine Sine and Cosine of the Angle
double cosAngle = (double)cos(radianAngle);
double sinAngle = (double)sin(radianAngle);
// Bitmap RGBA starting at last Pixel which holds 4 values, RGBA
sourceData = lightSrc->lastRow;
canvasData = lightCanvas->lastRow;
// Points to specific Pixel Data
RGSSRGBA *sourceRGBA, *canvasRGBA;
// Holds Position of X and Y to transfer the data to
double posX, posY;

// Iterate through the Source Pixels and draw them on to the Canvas
for (y = 0; y < heightSrc; y++)
{
for (x = 0; x < widthSrc; x++)
{
// Determine position on the Canvas Bitmap to draw
posX = x * cosAngle + y * sinAngle;
posY = x * sinAngle - y * cosAngle;
// Recenter (not working right)
posX += cX;
posY += cY;
// I dont have a clue what this does, I just copied and pasted
sourceRGBA = sourceData + y + (x * widthSrc);
canvasRGBA = canvasData + (int)posY + ((int)posX * widthCanvas);
// If new position on canvas is actually within the canvas
if (posY >= 0 && posY <= heightCanvas && posX >= 0 && posX <= widthCanvas)
{
// Transfer Data from the Source Image to the Canvas
canvasRGBA->red = sourceRGBA->red;
canvasRGBA->green = sourceRGBA->green;
canvasRGBA->blue = sourceRGBA->blue;
canvasRGBA->alpha = sourceRGBA->alpha;
}
}
}

// Debugging to display data inside DLL
if (showMsg == 1)
{
// Change the variable name from "angle" here for displaying data
// Remember to push the SHIFT key to use this Message Box
std::string myStr = std::to_string(angle);
MessageBoxA(NULL, myStr.c_str(), "DLL Message", MB_OK);
}

// Return Successful Rotation
return 1;
}


When rotated, I get a TON of garbage when angles are not 90s.  The box looking thing is supposed to be SOLID without all the noise.



First - CRASH - when the angle hits exactly 270.0 degrees, game just stops.  Non informative errors.  I figure division by 0 somewhere, but not sure exactly where.  I dont use the dll at all when the angle is 0.

Next, I cant quite figure out the math to center the image correctly.

Next, totally looks like shit.  Cant use for quality production.  I know there are better algorithms out there, but hey, its as far as I have gotten so far.  Im still quite confusitated by so much crap in c++ like, what the hell is "   void(*dmark) (void*); void(*dfree) (void*); "

Anyone wanna take a crack at making things look better?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Heretic86

June 22, 2016, 07:33:40 am #21 Last Edit: June 22, 2016, 07:53:42 am by Heretic86
You'll need the Light Script also where I plan to use the DLL file.  Too much code for one post and I will remove this post later due to code version being in an unstable Prototype Stage.

STANDALONE LIGHT SCRIPT - PROTOTYPE - NOT STABLE - NOT LEGAL FOR RELEASE OR DISTRIBUTION


Legal crap aside, here is how to use this so far.

INSTRUCTIONS
Spoiler: ShowHide
First, use some sort of Image Editing program to create a PNG with an Alpha channel.  A simple gradient circle will do.  It doesnt have to be fancy.  Then make a new folder in RPG Maker XP project Graphics and call it "Lights".  Put your Light Image in there.  The default name I look for is "Light1.png".

THis is the one I used if you are too lazy to make your own:
[spoiler]
http://downloads.chaos-project.com/heretic86/Light1.png


Next, make an Event, and give it a Comment in the first 10 lines or so that reads "\light[]" without the quotes.  You can put a custom file name between the two [] characters to give each event its own individual Lightsource Image.  \light[torch.png] for example.

Now, we need some shadows for the Lights to cut thru.  There are two ways to do this.  Indoor and Outdoor, or set the Time to Night.
- Indoor Switch -> Just set Switch 75 to ON

Once that SWITCH is turned on, the screen should be much darker, but still visible.  If you have a Light (Event with \light[] comment) on the screen, then the Light will cut out a part of the shadow that covers the screen.

Now, to kick in the DLL, set the ANGLE property of your event to anything BUT zero:
$game_map.events[3].light.angle = 30;

You might wanna use a parallel process to just keep adding 1 to the angle.  It defaults to 0.[/spoiler]

Script has some documentation but is not complete at this point.

I also have a ton of DEBUG stuff in there.  When Bitmaps are rotated, I am drawing a border around them so I can see the dimensions and position of the Bitmap that I use for creating the Light Sources.  Ignore the border.  Rotated Image is really looks like crap and I need advice.

If a Demo is needed, I'll upload one so I can get this stupid DLL part of this script out of the way.  10 edits later, I think Im done editing this post.  :P
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

KK20

Nice triple bro

Providing a demo would be better (and faster) for us. But seeing those screenshots, I don't really think there's any merit in even trying it.
I just started looking into making a DLL yesterday and got moderate progress using an abandoned project that I believe you looked at:
https://github.com/scanti/RPG-Maker-Bitmap-Functions
...which I just now realized Thallion worked on this.

Going to look into centering the axis of rotation and transferring the pixel data to a secondary bitmap and see where that takes me.

Regarding the "garbage", your C++ is looping through the source bitmap pixels when it should be the destination bitmap. That's why it's producing all these holes in your image.

For the crashes, it might be you are requesting pixel data for a coordinate outside of the bitmap. Maybe try moving the setting of sourceRGBA and canvasRGBA inside the posX/Y if statement.

For the weird things inside the structs, ignore them. You can think of the bitmap objects you are passing into the DLL as an array of various data. Once you do
((RGSSBITMAP*)(src_object << 1))

it kinda looks like
[flags, class_type, unknown_thing, another_unknown_thing, *bm]

Have you even tried removing the voids and seeing what happens to your DLL? I'm pretty sure it will crash since your *bm would be assigned to the address stored in 'unknown_thing', which should not be holding a BITMAPSTRUCT.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Heretic86

I was working on the Demo, just took longer to put together than I expected due to constant interruptions.

http://downloads.chaos-project.com/heretic86/LightDLL.zip

Havent changed any of the source code yet, but I'll try what you suggested. 

Thanks!
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

KK20

My Result
Spoiler: ShowHide

DLL:
Spoiler: ShowHide

typedef union {
unsigned int pixel;
struct {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
};
} RGSSRGBA;

typedef struct {
    DWORD flags;
    DWORD klass;
    void (*dmark) (void*);
    void (*dfree) (void*);
    BYTE *data; //B = 0, G = 1, R = 2, A = 3
} RGSSCOLOR;

typedef struct{
    DWORD unk1;
    DWORD unk2;
    BITMAPINFOHEADER *infoheader;
    RGSSRGBA *firstRow;
    RGSSRGBA *lastRow;
} RGSSBMINFO;

typedef struct{
    DWORD unk1;
    DWORD unk2;
    RGSSBMINFO *bminfo;
} BITMAPSTRUCT;

typedef struct{
    DWORD flags;
    DWORD klass;
    void (*dmark) (void*);
    void (*dfree) (void*);
    BITMAPSTRUCT *bm;
} RGSSBITMAP;

bool DLL_EXPORT Transform33(long bmp, float * matrix)
{
    RGSSBMINFO *bitmap = ((RGSSBITMAP*)(bmp<<1))->bm->bminfo;

    long width, height;
    RGSSRGBA *row;
RGSSRGBA *rowcopy;
    long x, y;
    float nx, ny;
    float cx, cy;
    unsigned char red,green,blue,alpha;

float transx, transy, transw;

    if(!bitmap)
return false;
    width = bitmap->infoheader->biWidth;
    height = bitmap->infoheader->biHeight;
    cx = (float)width / 2 - 0.001;
    cy = (float)height / 2 - 0.001;

rowcopy = new RGSSRGBA[width*height];
    row = bitmap->lastRow;
    memcpy(rowcopy,row,width*height*4);

RGSSRGBA *sourcepos;

    for ( y = 0; y < height; y++)
{
        for ( x = 0; x < width; x++)
{
    nx = x - cx;
    ny = y - cy;

transx=(float)(matrix[0]*nx + matrix[1]*ny + matrix[2]);
transy=(float)(matrix[3]*nx + matrix[4]*ny + matrix[5]);
transw=(float)(matrix[6]*nx + matrix[7]*ny + matrix[8]);

// Dividing by zero is bad

if (transw==0)
transw=(float)0.001;

transx=(transx + cx)/transw;
transy=(transy + cy)/transw;

if (transx<0 || transx>width || transy<0 || transy>height)
{
red=0;
green=0;
blue=0;
alpha=0;
}
else
{
sourcepos = rowcopy + (int)transx + ((int)transy * width);

red = sourcepos->red;
green = sourcepos->green;
blue = sourcepos->blue;
alpha = sourcepos->alpha;
}

row->red = red;
row->green = green;
row->blue = blue;
row->alpha = alpha;

            row++;
        }
    }

delete[]rowcopy;

    return true;
}

Note I still just pass in one bitmap object. I figured it's easier that way and less coding for me in the long run.

Ruby Test (place anywhere above Main, left/right to spin):
Spoiler: ShowHide


def new_bitmap(width, height, sin, cos)
  sin = sin.abs
  cos = cos.abs
 
  w = (width * cos + height * sin).to_i
  h = (width * sin + height * cos).to_i
 
  Bitmap.new(w, h)
end

class Float < Numeric
  def approx
    target = self.round
    return target if (self + 0.00001 >= target && self - 0.00001 <= target)
    return self
  end
end

 

RotateBitmap = Win32API.new('RotateBitmap','Transform33','lp','i')

s = Sprite.new
s.x = 200
s.y = 200
src = RPG::Cache.picture('square')
s.bitmap = Bitmap.new(96,96)
s.bitmap.blt(0, 0, src, Rect.new(0,0,96,96))
angle = 0

while true
  Graphics.update
  Input.update
  s.update
  old_angle = angle
 
  if Input.repeat?(Input::RIGHT)
    angle += 5
  elsif Input.repeat?(Input::LEFT)
    angle -= 5
  end
 
  if old_angle != angle
    angle %= 360
   
    rads = Math::PI * angle / 180
    sin = Math.sin(rads).approx.to_f
    cos = Math.cos(rads).approx.to_f
           
    arr = [cos, -sin, 0.0,
           sin, cos,  0.0,
           0.0, 0.0,  1.0]
           
    s.bitmap.clear
    s.bitmap.dispose
    s.bitmap = new_bitmap(96, 96, sin, cos)
   
    x = s.bitmap.rect.width - 96
    y = s.bitmap.rect.height - 96
   
    s.bitmap.blt(x/2, y/2, src, Rect.new(0,0,96,96))
    s.ox = x/2
    s.oy = y/2
   
    RotateBitmap.call(s.bitmap.object_id, arr.pack("F*"))

  end
 
end



Graphic used:

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Heretic86

If I were a girl, Id offer to have your babies!

Can I just use your dll and give you credit instead?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

KK20

Also give credit to scanti and TD. I also forgot to test rectangles, so better check that first.

Is there anything in the code you need clarification on?

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Heretic86

I'll give them credit too.

Rectangles get clipped.  Tried it.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Blizzard

Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Rectangles are fine. Just needed a couple tweaks to the Ruby test to get it working:

def new_bitmap(width, height, sin, cos)
  sin = sin.abs
  cos = cos.abs
 
  w = [(width * cos + height * sin).to_i, width].max
  h = [(width * sin + height * cos).to_i, height].max
 
  Bitmap.new(w, h)
end

class Float < Numeric
  def approx
    target = self.round
    return target if (self + 0.00001 >= target && self - 0.00001 <= target)
    return self
  end
end

 

RotateBitmap = Win32API.new('RotateBitmap','Transform33','lp','i')

s = Sprite.new
s.x = 200
s.y = 200
src = RPG::Cache.picture('rectangle')
bw = src.rect.width
bh = src.rect.height
s.bitmap = Bitmap.new(bw,bh)
s.bitmap.blt(0, 0, src, Rect.new(0,0,bw,bh))
angle = 0

while true
  Graphics.update
  Input.update
  s.update
  old_angle = angle
 
  if Input.repeat?(Input::RIGHT)
    angle += 5
  elsif Input.repeat?(Input::LEFT)
    angle -= 5
  end
 
  if old_angle != angle
    angle %= 360
   
    rads = Math::PI * angle / 180
    sin = Math.sin(rads).approx.to_f
    cos = Math.cos(rads).approx.to_f
           
    arr = [cos, -sin, 0.0,
           sin, cos,  0.0,
           0.0, 0.0,  1.0]
           
    s.bitmap.clear
    s.bitmap.dispose
    s.bitmap = new_bitmap(bw, bh, sin, cos)
   
    x = s.bitmap.rect.width - bw
    y = s.bitmap.rect.height - bh
   
    s.bitmap.blt(x/2, y/2, src, Rect.new(0,0,bw,bh))
    s.ox = x/2
    s.oy = y/2
   
    RotateBitmap.call(s.bitmap.object_id, arr.pack("F*"))

  end
 
end

So using that as a guide, it shouldn't be hard to incorporate it into the script now.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Heretic86

June 25, 2016, 08:42:46 am #30 Last Edit: June 25, 2016, 08:45:49 am by Heretic86
Quote from: Blizzard on June 25, 2016, 01:36:52 am
So you were finally able to get it done? :)


Im close.  Very close.  Lot of commenting needs to be done, a few features, cleanup, etc.  Other than a bit of trouble with a "Spotlight" feature, and like KK20 mentioned, Rectangles, its coming along very nicely.  Im fairly certain the DLL itself is done.  I had no choice but to use KK20's code for the DLL so gotta give credit where credit is due for all this help you guys are providing me with.

This looks kind of cool, right?

(Animated Gif, give it a moment...)

Aside from the nightmare I had with that dll stuff, Im now working on tying a couple of scripts together.  I already wrote a Rotate, Zoom, and Pendulum script so Im tying a bunch of features of that script together with the Light stuff so I dont end up rewriting the same code with the same features.

Other than that, it is just a matter of focusing on any other Features that users may want.  Hopefully as user friendly as I can make it!  Best of all, super high compatability, even with other Screen Resolution scripts!  I havent had a chance to test that out but since its a simple sprite that covers the screen to create the whole Light effect, just setting the size of that sprite in the Script Config as a variable should let it be compatible.  I mean, within reason.  If they get rid of the Event classes, not much I can do there.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Blizzard

Looks pretty good. :)
BTW, in my XPA_Window implementation there is a WriteLinear() method in the DLL which basically does zooming using linear interpolation. Feel free to use it.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Heretic86

@Blizz - I doubt Im good enough to do that yet.

DLL still gives me crashes.  KK20 suspects trying to draw outside the bitmap.

I am doing some specific things that I thought would work that always exist when the crash occurs.  For the "spotlight" effect, Im using stretch_blt to put the original source image into a Bitmap Canvas to rotate.  Just creating a Bitmap.new(new_w, new_h) also causes a crash with to blt or stretch.  The unaltered New Bitmap also crashes upon rotation.  "Ordinary" rotating doesnt cause crashes, but stretching does cause random crashes.

KK20rotate.cpp
Spoiler: ShowHide
// KK20Rotate.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

typedef union {
unsigned int pixel;
struct {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
};
} RGSSRGBA;

typedef struct {
DWORD flags;
DWORD klass;
void(*dmark) (void*);
void(*dfree) (void*);
BYTE *data; //B = 0, G = 1, R = 2, A = 3
} RGSSCOLOR;

typedef struct {
DWORD unk1;
DWORD unk2;
BITMAPINFOHEADER *infoheader;
RGSSRGBA *firstRow;
RGSSRGBA *lastRow;
} RGSSBMINFO;

typedef struct {
DWORD unk1;
DWORD unk2;
RGSSBMINFO *bminfo;
} BITMAPSTRUCT;

typedef struct {
DWORD flags;
DWORD klass;
void(*dmark) (void*);
void(*dfree) (void*);
BITMAPSTRUCT *bm;
} RGSSBITMAP;

extern "C" _declspec (dllexport) bool RotateRGSSBmp(long bmp, float * matrix)
{
RGSSBMINFO *bitmap = ((RGSSBITMAP*)(bmp << 1))->bm->bminfo;

long width, height;
RGSSRGBA *row;
RGSSRGBA *rowcopy;
long x, y;
float nx, ny;
float cx, cy;
unsigned char red, green, blue, alpha;

float transx, transy, transw;

if (!bitmap)
return false;
width = bitmap->infoheader->biWidth;
height = bitmap->infoheader->biHeight;
cx = (float)width / 2 + 0.0001;
cy = (float)height / 2 + 0.0001;

rowcopy = new RGSSRGBA[width*height];
row = bitmap->lastRow;
memcpy(rowcopy, row, width*height * 4);

RGSSRGBA *sourcepos;

for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
nx = x - cx;
ny = y - cy;

transx = (float)(matrix[0] * nx + matrix[1] * ny + matrix[2]);
transy = (float)(matrix[3] * nx + matrix[4] * ny + matrix[5]);
transw = (float)(matrix[6] * nx + matrix[7] * ny + matrix[8]);

// Dividing by zero is bad
if (transw == 0)
transw = (float)0.001;

transx = (transx + cx) / transw;
transy = (transy + cy) / transw;

if (transx < 0 || transx > width || transy < 0 || transy > height)
{
red = 0;
green = 0;
blue = 0;
alpha = 0;
}
else
{
sourcepos = rowcopy + (int)transx + ((int)transy * width);

red = sourcepos->red;
green = sourcepos->green;
blue = sourcepos->blue;
alpha = sourcepos->alpha;
}

row->red = red;
row->green = green;
row->blue = blue;
row->alpha = alpha;

row++;
}
}

delete[]rowcopy;

return true;
}


I dont have a clue how to debug this.  When the game crashes, it just crashes.  No debug, no line number, no specific error, just "Stopped Working".

Thoughts?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Blizzard

It would be best if you set up some debug code with fprintf() that writes stuff to a file so you can see step by step what's going on.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Just a head's up, the +0.0001 should really be a minus (I don't know why you changed it). When using the square graphic in my example, if you remove the addition entirely, it was drawing the wrong row of pixels at every 90, 180, or 270 degrees. Watch the edges of the square and you will see the error.
Spoiler: ShowHide


Since cx and cy essentially cut the graphic width/height in half, you would get 48 for the 96x96 square graphic. Assuming 90 degrees, sin would be 1 and cos would be 0. If our loop variables (x,y) are (0,0), we multiply -48 (subtracted by cx and cy) to sin and cos and get transx and transy to be 48 and -48 respectively. Add cx and cy back to them and you get the pixel coordinate (96, 0), which is just outside of the bitmap.

If we made cx and cy to be barely 48 (hence subtract by 0.0001), we can still ensure that, at the end, we get (95,0).

And I realized that it can't be out of bounds since the if-statement at the end ensures we are always in bounds. Definitely suggest the printing to a text file if you know the DLL is truly causing it.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Heretic86

June 28, 2016, 03:09:34 am #35 Last Edit: June 28, 2016, 03:14:58 am by Heretic86
Oops, I forgot to put that back in...

This is what I got when monkeying with attaching the debugger to game.exe

The thread 0xf84 has exited with code 0 (0x0).
Unhandled exception at 0x10003A70 in Game.exe: 0xC0000005: Access violation reading location 0x10003A70.

Exception thrown at 0x10003A70 in Game.exe: 0xC0000005: Access violation executing location 0x10003A70.

Unhandled exception at 0x10003A70 in Game.exe: 0xC0000005: Access violation reading location 0x10003A70.

Exception thrown at 0x10003A70 in Game.exe: 0xC0000005: Access violation executing location 0x10003A70.


Donut have a clue.  All greek.  Doesnt point at anything in either source code.

---

Would RPG Maker dll versions have anything to do with it?  Im running on the 102e.dll by the way...
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Blizzard

Most likely accessing data outside of the allowed rect.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Heretic86

Since this is related to the C++ part of the dynamic lighting, I'll ask in this thread.

Although I have heard the terms "linear interpolation", "bilinear interpolation" and "nearest neighbor", as far as the code goes (which I have not seen), what is the difference between these methods?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

KK20

So given the destination coordinate (x,y), you throw this into your rotation algorithm and receive the coordinate (x1,y1). What you do with this new coordinate now depends on what interpolation you want to use.

Nearest neighbor, as is present in the current DLL, takes the pixel in the source image that is at the specified coordinates you calculated. If the coordinate is a float, it is usually rounded to the nearest integer, but the DLL currently ignores anything after the decimal point (it's up to you if you want N.5 to return N or N+1).

Meanwhile, Bi-linear interpolation keeps the float in your coordinate. Rather than taking a pixel from your source directly, it uses a "system of averages" to generate an entirely new pixel color based on the surrounding pixels.

If you could imagine (0,0) being the top left pixel of your image, (0.5,0) would be the right half of (0,0) and the left half of (1,0). You take the colors of these two pixels, average them out, and assign this to your destination bitmap.

Linear interpolation doesn't make sense in this case since we're dealing with 2D graphics. It's more for mathematical graphs. But there are many kinds of n-linear interpolations out there that we just group them all up under the same name.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

July 02, 2016, 04:00:33 am #39 Last Edit: July 02, 2016, 04:09:19 am by Blizzard
Yeah, I was gonna say that. In 2D it's actually called bi-linear interpolation, because you interpolate on the X and Y axises. But the idea is basically the same.

Let's say we have 2 pixels: green and white. Or better said, we have 2x1 image with the values (0, 255, 0) and (255, 255, 255). Now, if would stretch that to 4 pixels, depending on the algorithm used, you will get a different result. Nearest neighbor will give you (0, 255, 0), (0, 255, 0), (255, 255, 255), (255, 255, 255) while lerp will give you (0, 255, 0), (85, 255, 85), (170, 255, 170), (255, 255, 255). Since the two pixels in between don't exist in the initial image, their values need to be calculated in a certain way. Nearest neighbor just takes a copy of the "nearest pixel" while lerp calculates the values as an average between the "extremes" (which are the original 2 pixels), depending on their distance from these extremes. So the second pixel will be a slightly brighter shade of green and the third a much brighter shade of green.

There are a few minor problems with bi-linear interpolation since you have to decide how to treat the image. Applying lerp to an image where you consider the "center of the pixel" as the reference point will yield difference results than if you consider the "top-left corner of the pixel" as reference point. And this also makes a lot of sense in terms of pixel data when working with floats. If you take the first pixel, its index is 0. The second one is 1. But logically you can still go to a coordinate like 1.99999999 which is virtually the top-right corner of the second pixel. I took this into account when writing my algorithm in XPA_Window which is why I keep suggesting you use it. xD I had to adjust the values and parameters for hours until I finally got it right. The trickiest part in this was to make sure that both upscaling and downscaling work properly since there seem to be logical differences in how you're supposed to treat the pixels. But once I actually got the algorithm right, the problem vanished by itself which also kinda confirmed that I finally did it right. xD
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.