JacksEscape/render_util.cpp

129 lines
3.0 KiB
C++
Raw Normal View History

#include "render_util.h"
2024-03-19 11:59:09 +08:00
#include "camera.h"
#include "render_pattern.h"
#include "easyx.h"
2024-03-19 11:59:09 +08:00
#include "types.h"
#include "util/vector.h"
2024-03-19 11:59:09 +08:00
#include "app.h"
#include <string.h>
#include <stdio.h>
2024-03-19 11:59:09 +08:00
#include <math.h>
#include <wingdi.h>
extern "C" {
static vector_Vector *tbuf;
#ifdef __MINGW32__
#define NCHAR char
#else
#define NCHAR wchar_t
#endif
void render_DrawText(int x, int y, const char *str) {
if (!tbuf)
tbuf = vector_Create(sizeof(NCHAR));
int cx = x, cy = y;
const NCHAR zero = 0;
vector_Clear(tbuf);
int len = strlen(str);
2024-03-05 14:26:39 +08:00
int i = 0;
while (i < len) {
if (str[i] == '\n') {
vector_Push(tbuf, &zero);
outtextxy(cx, cy, (LPCTSTR)vector_Data(tbuf));
cy += TEXTHEIGHT;
vector_Clear(tbuf);
} else {
NCHAR wc = str[i];
vector_Push(tbuf, &wc);
}
i++;
}
if (vector_Size(tbuf) > 0) {
vector_Push(tbuf, &zero);
outtextxy(cx, cy, (LPCTSTR)vector_Data(tbuf));
vector_Clear(tbuf);
}
}
2024-03-19 11:59:09 +08:00
2024-03-25 14:59:00 +08:00
const FillMode render_ModeDefault = {
2024-03-19 11:59:09 +08:00
.rop2 = R2_COPYPEN,
.style = BS_SOLID,
.hatch = 0,
.rotate = {.microseconds = 0},
2024-03-19 15:14:23 +08:00
.dissolve = {.microseconds = 0},
.fadein = false};
2024-03-25 14:59:00 +08:00
const FillMode render_ModeInverse = {
.rop2 = R2_NOT,
.style = BS_SOLID,
.hatch = 0,
.rotate = {.microseconds = 0},
.dissolve = {.microseconds = 0},
.fadein = false};
2024-03-19 11:59:09 +08:00
void render_SetModes(FillMode mode, TimePoint since) {
if (mode.dissolve.microseconds != 0) {
// Dissolve mode
double progress = duration_Seconds(time_Since(since)) / duration_Seconds(mode.dissolve);
2024-03-19 15:14:23 +08:00
if (mode.fadein)
setfillstyle(render_DissolvePatternIn(progress)); // progress is capped into [0,1] in this func
else
setfillstyle(render_DissolvePatternOut(progress));
2024-03-19 11:59:09 +08:00
setrop2(R2_COPYPEN);
return;
}
if (mode.rotate.microseconds != 0) {
// Rotate mode
int steps = (int)round(duration_Seconds(time_Since(since)) / duration_Seconds(mode.rotate));
2024-03-19 11:59:09 +08:00
static const long hatches[] = {HS_HORIZONTAL, HS_FDIAGONAL, HS_VERTICAL, HS_BDIAGONAL};
setfillstyle(BS_HATCHED, hatches[steps % 4], NULL);
setrop2(R2_COPYPEN);
return;
}
// Normal mode
setfillstyle(mode.style, mode.hatch, NULL);
setrop2(mode.rop2);
}
2024-03-19 15:14:23 +08:00
void render_FillScreen() {
solidrectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
2024-03-19 11:59:09 +08:00
}
2024-03-19 15:14:23 +08:00
void render_FillRectW(App *app, Box2 rect) {
2024-03-19 11:59:09 +08:00
if (app->camera)
rect = camera_TransformBox2(app->camera, rect);
else
fprintf(stderr, "[WARN][render_FillRectW] called without an active camera system\n");
solidrectangle(
2024-03-19 11:59:09 +08:00
(int)round(rect.lefttop.x),
(int)round(rect.lefttop.y),
(int)round(rect.lefttop.x + rect.size.x),
(int)round(rect.lefttop.y + rect.size.y));
}
2024-03-19 15:14:23 +08:00
void render_FillCircleW(App *app, Vec2 center, double radius) {
2024-03-19 11:59:09 +08:00
if (app->camera) {
center = camera_TransformVec2(app->camera, center);
radius = camera_TransformSize(app->camera, vec2(radius, 0)).x; // TODO non-aspect scaling
} else
fprintf(stderr, "[WARN][render_FillCircleW] called without an active camera system\n");
solidcircle(
2024-03-19 11:59:09 +08:00
(int)round(center.x),
(int)round(center.y),
(int)round(radius));
}
}