mirror of
https://github.com/Garhoogin/NitroPaint.git
synced 2025-06-18 14:25:31 -04:00
Add force affine+double size to NANR viewer
This commit is contained in:
parent
acb3ff1ac8
commit
ca3b10a615
@ -737,7 +737,8 @@ static void AnmViewerRenderGlyphListImage(NANRVIEWERDATA *data, int i) {
|
||||
AnmViewerCalcTransformMatrix(0.0f, 0.0f, sx, sy, rot, (double) frm.px, (double) frm.py, &mtx[0][0], trans);
|
||||
CellViewerRenderCell(data->cellRender, NULL, ncer, ncgr, nclr, frm.index, cell,
|
||||
FloatToInt(trans[0]), FloatToInt(trans[1]),
|
||||
mtx[0][0], mtx[0][1], mtx[1][0], mtx[1][1]);
|
||||
mtx[0][0], mtx[0][1], mtx[1][0], mtx[1][1],
|
||||
data->forceAffine, data->forceDoubleSize);
|
||||
}
|
||||
|
||||
//next, crop the rendered cell
|
||||
@ -1252,6 +1253,20 @@ static void AnmViewerCmdOnNewSequence(HWND hWnd, HWND hWndCtl, int notif, void *
|
||||
AnmViewerSetCurrentSequence(data, data->nanr.nSequences - 1, TRUE);
|
||||
}
|
||||
|
||||
static void AnmViewerCmdOnToggleForceAffine(HWND hWnd, HWND hWndCtl, int notif, void *param) {
|
||||
NANRVIEWERDATA *data = (NANRVIEWERDATA *) param;
|
||||
data->forceAffine = GetCheckboxChecked(hWndCtl);
|
||||
InvalidateRect(data->hWndPreview, NULL, FALSE);
|
||||
InvalidateRect(data->hWndAnimList, NULL, FALSE);
|
||||
}
|
||||
|
||||
static void AnmViewerCmdOnToggleForceDoubleSize(HWND hWnd, HWND hWndCtl, int notif, void *param) {
|
||||
NANRVIEWERDATA *data = (NANRVIEWERDATA *) param;
|
||||
data->forceDoubleSize = GetCheckboxChecked(hWndCtl);
|
||||
InvalidateRect(data->hWndPreview, NULL, FALSE);
|
||||
InvalidateRect(data->hWndAnimList, NULL, FALSE);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK AnmViewerSeqListSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT idSubclass, DWORD_PTR data_) {
|
||||
NANRVIEWERDATA *data = (NANRVIEWERDATA *) data_;
|
||||
|
||||
@ -1277,6 +1292,7 @@ static void AnmViewerOnCreate(NANRVIEWERDATA *data) {
|
||||
data->showBorders = 1;
|
||||
|
||||
data->hWndAnimList = AnmViewerAnimListCreate(data);
|
||||
data->hWndNewSequence = CreateButton(data->hWnd, L"New Sequence", 0, 0, 0, 0, FALSE);
|
||||
data->hWndPreview = CreateWindow(L"NanrPreviewClass", L"", WS_VISIBLE | WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS,
|
||||
300, 0, 300, 300, data->hWnd, NULL, NULL, NULL);
|
||||
FbCreate(&data->fb, data->hWndPreview, 0, 0);
|
||||
@ -1284,7 +1300,8 @@ static void AnmViewerOnCreate(NANRVIEWERDATA *data) {
|
||||
data->hWndPlayPause = CreateButton(data->hWnd, L"Play", 0, 0, 0, 0, FALSE);
|
||||
data->hWndStop = CreateButton(data->hWnd, L"Step", 0, 0, 0, 0, FALSE);
|
||||
data->hWndShowFrames = CreateButton(data->hWnd, L"Frames", 0, 0, 0, 0, FALSE);
|
||||
data->hWndNewSequence = CreateButton(data->hWnd, L"New Sequence", 0, 0, 0, 0, FALSE);
|
||||
data->hWndForceAffine = CreateCheckbox(data->hWnd, L"Force Affine", 0, 0, 0, 0, FALSE);
|
||||
data->hWndForceDoubleSize = CreateCheckbox(data->hWnd, L"Force Double Size", 0, 0, 0, 0, FALSE);
|
||||
|
||||
LPCWSTR playModes[] = {
|
||||
//L"[\xFF0F\xFFE3\xFFE3\xFFE3] Forward",
|
||||
@ -1304,6 +1321,8 @@ static void AnmViewerOnCreate(NANRVIEWERDATA *data) {
|
||||
UiCtlMgrAddCommand(&data->mgr, data->hWndShowFrames, BN_CLICKED, AnmViewerCmdOnShowFrames);
|
||||
UiCtlMgrAddCommand(&data->mgr, data->hWndPlayMode, CBN_SELCHANGE, AnmViewerCmdOnSetPlayMode);
|
||||
UiCtlMgrAddCommand(&data->mgr, data->hWndNewSequence, BN_CLICKED, AnmViewerCmdOnNewSequence);
|
||||
UiCtlMgrAddCommand(&data->mgr, data->hWndForceAffine, BN_CLICKED, AnmViewerCmdOnToggleForceAffine);
|
||||
UiCtlMgrAddCommand(&data->mgr, data->hWndForceDoubleSize, BN_CLICKED, AnmViewerCmdOnToggleForceDoubleSize);
|
||||
|
||||
SetWindowSubclass(data->hWndAnimList, AnmViewerSeqListSubclassProc, 2, (DWORD_PTR) data);
|
||||
}
|
||||
@ -1332,6 +1351,10 @@ static int AnmViewerOnSize(NANRVIEWERDATA *data, WPARAM wParam, LPARAM lParam) {
|
||||
int frameButtonX = cellPropX + ctlWidthWide + UI_SCALE_COORD(10, dpiScale);
|
||||
MoveWindow(data->hWndShowFrames, frameButtonX, 0, UI_SCALE_COORD(75, dpiScale), ctlHeight, TRUE);
|
||||
|
||||
int forceCtlX = frameButtonX + UI_SCALE_COORD(75, dpiScale) + UI_SCALE_COORD(10, dpiScale);
|
||||
MoveWindow(data->hWndForceAffine, forceCtlX, 0, UI_SCALE_COORD(80, dpiScale), ctlHeight, TRUE);
|
||||
MoveWindow(data->hWndForceDoubleSize, forceCtlX + UI_SCALE_COORD(80, dpiScale), 0, UI_SCALE_COORD(125, dpiScale), ctlHeight, TRUE);
|
||||
|
||||
if (wParam == SIZE_RESTORED) InvalidateRect(data->hWndPreview, NULL, TRUE); //full update
|
||||
return DefMDIChildProc(data->hWnd, WM_SIZE, wParam, lParam);
|
||||
}
|
||||
@ -1577,7 +1600,8 @@ static void AnmViewerPreviewOnPaint(NANRVIEWERDATA *data) {
|
||||
AnmViewerCalcTransformMatrix(0.0, 0.0, sx, sy, rot, (double) frm.px, (double) frm.py, &mtx[0][0], trans);
|
||||
CellViewerRenderCell(data->cellRender, NULL, ncer, ncgr, nclr, frm.index, cell,
|
||||
FloatToInt(trans[0]), FloatToInt(trans[1]),
|
||||
mtx[0][0], mtx[0][1], mtx[1][0], mtx[1][1]);
|
||||
mtx[0][0], mtx[0][1], mtx[1][0], mtx[1][1],
|
||||
data->forceAffine, data->forceDoubleSize);
|
||||
}
|
||||
|
||||
//ensure framebuffer size
|
||||
|
@ -33,6 +33,9 @@ typedef struct {
|
||||
int direction; // current animation direction
|
||||
int resetFlag; // sequence is stopped and will be restarted
|
||||
|
||||
int forceAffine; // force affine mode for OBJ
|
||||
int forceDoubleSize; // force double size for OBJ
|
||||
|
||||
int mouseDown;
|
||||
int hit;
|
||||
int mouseDownHit;
|
||||
@ -58,6 +61,8 @@ typedef struct {
|
||||
HWND hWndAnimList; // animation list
|
||||
HWND hWndPreview; // preview
|
||||
HWND hWndNewSequence;
|
||||
HWND hWndForceAffine;
|
||||
HWND hWndForceDoubleSize;
|
||||
|
||||
HWND hWndPlayPause;
|
||||
HWND hWndStop;
|
||||
|
@ -790,7 +790,7 @@ static void CellViewerCopyDIB(NCERVIEWERDATA *data) {
|
||||
tmpCell->useEx2d = cell->useEx2d;
|
||||
tmpCell->ex2dCharNames = exAttr;
|
||||
|
||||
CellViewerRenderCell(buf, NULL, &data->ncer, ncgr, nclr, data->cell, tmpCell, 0, 0, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
CellViewerRenderCell(buf, NULL, &data->ncer, ncgr, nclr, data->cell, tmpCell, 0, 0, 1.0f, 0.0f, 0.0f, 1.0f, 0, 0);
|
||||
free(tmpCell);
|
||||
free(selAttr);
|
||||
if (exAttr != NULL) free(exAttr);
|
||||
@ -1029,7 +1029,9 @@ void CellViewerRenderCell(
|
||||
double a,
|
||||
double b,
|
||||
double c,
|
||||
double d
|
||||
double d,
|
||||
int forceAffine,
|
||||
int forceDoubleSize
|
||||
) {
|
||||
//adjust (X,Y) offset to center of preview
|
||||
xOffs += 256;
|
||||
@ -1037,7 +1039,7 @@ void CellViewerRenderCell(
|
||||
|
||||
//get VRAM transfer entry
|
||||
CHAR_VRAM_TRANSFER *vramTransfer = NULL;
|
||||
if (ncer->vramTransfer != NULL) vramTransfer = &ncer->vramTransfer[cellIndex];
|
||||
if (ncer != NULL && ncer->vramTransfer != NULL && cellIndex != -1) vramTransfer = &ncer->vramTransfer[cellIndex];
|
||||
|
||||
//if cell is NULL, we use cell at cellInex.
|
||||
if (cell == NULL) {
|
||||
@ -1076,7 +1078,7 @@ void CellViewerRenderCell(
|
||||
CellViewerRenderObj(block, &info, ncgr, nclr, ncer->mappingMode, vramTransfer);
|
||||
|
||||
//HV flip? Only if not affine!
|
||||
if (!info.rotateScale) {
|
||||
if (!(info.rotateScale || forceAffine)) {
|
||||
COLOR32 temp[64];
|
||||
if (info.flipY) {
|
||||
for (int i = 0; i < info.height / 2; i++) {
|
||||
@ -1097,17 +1099,23 @@ void CellViewerRenderCell(
|
||||
}
|
||||
}
|
||||
|
||||
//apply transformation matrix to OBJ position
|
||||
int x = info.x;
|
||||
int y = info.y;
|
||||
if (!isMtxIdentity) {
|
||||
//adjust sign of OBJ coordinates, since we rely on signed coordinates
|
||||
if (x >= 256) x -= 512;
|
||||
if (y >= 128) y -= 256;
|
||||
int doubleSize = info.doubleSize;
|
||||
if ((info.rotateScale || forceAffine) && forceDoubleSize) doubleSize = 1;
|
||||
|
||||
//apply transformation matrix to OBJ position
|
||||
int x = SEXT9(info.x);
|
||||
int y = SEXT8(info.y);
|
||||
|
||||
//when forcing double size on an OBJ that isn't naturally double size, we'll correct its position.
|
||||
if ((forceDoubleSize && (info.rotateScale || forceAffine)) && !info.doubleSize) {
|
||||
x -= info.width / 2;
|
||||
y -= info.height / 2;
|
||||
}
|
||||
|
||||
if (!isMtxIdentity) {
|
||||
//adjust coordinates by correction for double-size
|
||||
int realWidth = info.width << info.doubleSize;
|
||||
int realHeight = info.height << info.doubleSize;
|
||||
int realWidth = info.width << doubleSize;
|
||||
int realHeight = info.height << doubleSize;
|
||||
int movedX = x + realWidth / 2;
|
||||
int movedY = y + realHeight / 2;
|
||||
|
||||
@ -1117,9 +1125,9 @@ void CellViewerRenderCell(
|
||||
}
|
||||
|
||||
//copy data
|
||||
if (!info.rotateScale) {
|
||||
if (!(info.rotateScale || forceAffine)) {
|
||||
//adjust for double size
|
||||
if (info.doubleSize) {
|
||||
if (doubleSize) {
|
||||
x += info.width / 2;
|
||||
y += info.height / 2;
|
||||
}
|
||||
@ -1138,8 +1146,8 @@ void CellViewerRenderCell(
|
||||
}
|
||||
} else {
|
||||
//transform about center
|
||||
int realWidth = info.width << info.doubleSize;
|
||||
int realHeight = info.height << info.doubleSize;
|
||||
int realWidth = info.width << doubleSize;
|
||||
int realHeight = info.height << doubleSize;
|
||||
double cx = (realWidth - 1) * 0.5; // rotation center X in OBJ
|
||||
double cy = (realHeight - 1) * 0.5; // rotation center Y in OBJ
|
||||
|
||||
@ -1152,7 +1160,7 @@ void CellViewerRenderCell(
|
||||
int srcY = FloatToInt(((((double) k) - cx) * invC + (((double) j) - cy) * invD) + cy);
|
||||
|
||||
//if double size, adjust source coordinate by the excess size
|
||||
if (info.doubleSize) {
|
||||
if (doubleSize) {
|
||||
srcX -= realWidth / 4;
|
||||
srcY -= realHeight / 4;
|
||||
}
|
||||
@ -1173,7 +1181,7 @@ void CellViewerRenderCell(
|
||||
}
|
||||
|
||||
static void CellViewerRenderCellByIndex(COLOR32 *buf, int *covbuf, NCER *ncer, NCGR *ncgr, NCLR *nclr, int cellno) {
|
||||
CellViewerRenderCell(buf, covbuf, ncer, ncgr, nclr, cellno, NULL, 0, 0, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
CellViewerRenderCell(buf, covbuf, ncer, ncgr, nclr, cellno, NULL, 0, 0, 1.0f, 0.0f, 0.0f, 1.0f, 0, 0);
|
||||
}
|
||||
|
||||
static void CellViewerUpdateCellRender(NCERVIEWERDATA *data) {
|
||||
|
@ -90,6 +90,22 @@ HWND CreateNcerViewerImmediate(int x, int y, int width, int height, HWND hWndPar
|
||||
|
||||
void CellViewerRenderGridlines(FrameBuffer *fb, int scale, int scrollX, int scrollY);
|
||||
|
||||
void CellViewerRenderCell(COLOR32 *px, int *covbuf, NCER *ncer, NCGR *ncgr, NCLR *nclr, int cellIndex, NCER_CELL *cell, int xOffs, int yOffs, double a, double b, double c, double d);
|
||||
void CellViewerRenderCell(
|
||||
COLOR32 *px, // output 512x256 pixel buffer
|
||||
int *covbuf, // output coverage buffer (optional)
|
||||
NCER *ncer, // cell data bank
|
||||
NCGR *ncgr, // character graphics
|
||||
NCLR *nclr, // color palette
|
||||
int cellIndex, // cell index (required if cell is in the cell data bank)
|
||||
NCER_CELL *cell, // cell data (required if not in the cell data bank)
|
||||
int xOffs, // horizontal displacement of render
|
||||
int yOffs, // vertical displacement of render
|
||||
double a, // affine parameter A
|
||||
double b, // affine parameter B
|
||||
double c, // affine parameter C
|
||||
double d, // affine parameter D
|
||||
int forceAffine, // forces all OBJ to be in affine mode
|
||||
int forceDoubleSize // forces all affine OBJ to be in double size mode
|
||||
);
|
||||
|
||||
COLOR32 *CellViewerCropRenderedCell(COLOR32 *px, int width, int height, int *pMinX, int *pMinY, int *outWidth, int *outHeight);
|
||||
|
Loading…
Reference in New Issue
Block a user