diff --git a/include/parts.h b/include/parts.h index 14d050a..c1d52ad 100644 --- a/include/parts.h +++ b/include/parts.h @@ -28,19 +28,24 @@ void PE_Update(int passed_time, bool message_window_show); void PE_UpdateParts(int passed_time, bool is_skip, bool message_window_show); bool PE_SetPartsCG(int parts_no, struct string *cg_name, int sprite_deform, int state); bool PE_SetPartsCG_by_index(int parts_no, int cg_no, int sprite_deform, int state); +bool PE_SetPartsCGSurfaceArea(int parts_no, int x, int y, int w, int h, int state); int PE_GetPartsCGNumber(int parts_no, int state); bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_time, int state); +bool PE_SetLoopCGSurfaceArea(int parts_no, int x, int y, int w, int h, int state); bool PE_SetHGaugeCG(int parts_no, struct string *cg_name, int state); bool PE_SetHGaugeCG_by_index(int parts_no, int cg_no, int state); bool PE_SetHGaugeRate(int parts_no, int numerator, int denominator, int state); +bool PE_SetHGaugeSurfaceArea(int parts_no, int x, int y, int w, int h, int state); bool PE_SetVGaugeCG(int parts_no, struct string *cg_name, int state); bool PE_SetVGaugeCG_by_index(int parts_no, int cg_no, int state); bool PE_SetVGaugeRate(int parts_no, int numerator, int denominator, int state); +bool PE_SetVGaugeSurfaceArea(int parts_no, int x, int y, int w, int h, int state); bool PE_SetNumeralCG_by_index(int parts_no, int cg_no, int state); bool PE_SetNumeralLinkedCGNumberWidthWidthList_by_index(int parts_no, int cg_no, int w0, int w1, int w2, int w3, int w4, int w5, int w6, int w7, int w8, int w9, int w_minus, int w_comma, int state); bool PE_SetNumeralNumber(int parts_no, int n, int state); bool PE_SetNumeralShowComma(int parts_no, bool show_comma, int state); bool PE_SetNumeralSpace(int parts_no, int space, int state); +bool PE_SetNumeralSurfaceArea(int parts_no, int x, int y, int w, int h, int state); bool PE_SetPartsRectangleDetectionSize(int PartsNumber, int Width, int Height, int State); bool PE_SetPartsFlash(int PartsNumber, struct string *pIFlashFileName, int State); bool PE_IsPartsFlashEnd(int PartsNumber, int State); @@ -87,6 +92,7 @@ bool PE_IsExist(int parts_no); bool PE_AddCreateCGToProcess(int parts_no, struct string *cg_name, int state); bool PE_AddFillAlphaColorToPartsConstructionProcess(int parts_no, int x, int y, int w, int h, int r, int g, int b, int a, int state); bool PE_BuildPartsConstructionProcess(int parts_no, int state); +bool PE_SetPartsConstructionSurfaceArea(int parts_no, int x, int y, int w, int h, int state); // input.c void PE_UpdateInputState(int passed_time); @@ -127,6 +133,7 @@ int PE_GetMotionEndTime(void); // text.c bool PE_SetText(int parts_no, struct string *text, int state); bool PE_AddPartsText(int parts_no, struct string *text, int state); +bool PE_SetPartsTextSurfaceArea(int parts_no, int x, int y, int w, int h, int state); bool PE_SetFont(int parts_no, int type, int size, int r, int g, int b, float bold_weight, int edge_r, int edge_g, int edge_b, float edge_weight, int state); bool PE_SetPartsFontType(int parts_no, int type, int state); bool PE_SetPartsFontSize(int parts_no, int size, int state); diff --git a/shaders/parts.f.glsl b/shaders/parts.f.glsl new file mode 100644 index 0000000..e3f5de4 --- /dev/null +++ b/shaders/parts.f.glsl @@ -0,0 +1,37 @@ +/* Copyright (C) 2019 Nunuhara Cabbage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +uniform sampler2D tex; +uniform float alpha_mod; +uniform vec2 bot_left; +uniform vec2 top_right; + +in vec2 tex_coord; +out vec4 frag_color; + +float point_in_rect(vec2 p, vec2 bot_left, vec2 top_right) { + vec2 s = step(bot_left, p) - step(top_right, p); + return s.x * s.y; +} + +void main() { + vec2 size = vec2(textureSize(tex, 0)); + vec2 bl = bot_left / size; + vec2 tr = top_right / size; + + frag_color = texture(tex, tex_coord) * point_in_rect(tex_coord, bl, tr); + frag_color.a *= alpha_mod; +} diff --git a/src/hll/GUIEngine.c b/src/hll/GUIEngine.c index f2acc43..2b81059 100644 --- a/src/hll/GUIEngine.c +++ b/src/hll/GUIEngine.c @@ -340,7 +340,6 @@ HLL_QUIET_UNIMPLEMENTED(0, int, GUIEngine, GetMessageType); //static bool GUIEngine_Parts_SetPartsCG(int PartsNumber, string pCGName, int SpriteDeform, int State); //static void GUIEngine_Parts_GetPartsCGName(int PartsNumber, ref string pCGName, int State); //static bool GUIEngine_Parts_SetPartsCGSurfaceArea(int PartsNumber, int X, int Y, int Width, int Height, int State); -HLL_QUIET_UNIMPLEMENTED(0, bool, GUIEngine, Parts_SetPartsCGSurfaceArea, int parts_number, int x, int y, int w, int h, int state); //static bool GUIEngine_Parts_SetLoopCG(int PartsNumber, string pCGName, int StartNo, int NumofCG, int TimePerCG, int State); //static bool GUIEngine_Parts_SetLoopCGSurfaceArea(int PartsNumber, int X, int Y, int Width, int Height, int State); //static bool GUIEngine_Parts_SetText(int PartsNumber, string pIText, int State); @@ -809,33 +808,33 @@ HLL_LIBRARY(GUIEngine, HLL_TODO_EXPORT(GetMultiTextBoxCGName, GUIEngine_GetMultiTextBoxCGName), HLL_EXPORT(Parts_SetPartsCG, PE_SetPartsCG), HLL_TODO_EXPORT(Parts_GetPartsCGName, GUIEngine_Parts_GetPartsCGName), - HLL_EXPORT(Parts_SetPartsCGSurfaceArea, GUIEngine_Parts_SetPartsCGSurfaceArea), + HLL_EXPORT(Parts_SetPartsCGSurfaceArea, PE_SetPartsCGSurfaceArea), HLL_TODO_EXPORT(Parts_SetLoopCG, GUIEngine_Parts_SetLoopCG), - HLL_TODO_EXPORT(Parts_SetLoopCGSurfaceArea, GUIEngine_Parts_SetLoopCGSurfaceArea), - HLL_TODO_EXPORT(Parts_SetText, GUIEngine_Parts_SetText), - HLL_TODO_EXPORT(Parts_AddPartsText, GUIEngine_Parts_AddPartsText), + HLL_EXPORT(Parts_SetLoopCGSurfaceArea, PE_SetLoopCGSurfaceArea), + HLL_EXPORT(Parts_SetText, PE_SetText), + HLL_EXPORT(Parts_AddPartsText, PE_AddPartsText), HLL_TODO_EXPORT(Parts_DeletePartsTopTextLine, GUIEngine_Parts_DeletePartsTopTextLine), - HLL_TODO_EXPORT(Parts_SetPartsTextSurfaceArea, GUIEngine_Parts_SetPartsTextSurfaceArea), + HLL_EXPORT(Parts_SetPartsTextSurfaceArea, PE_SetPartsTextSurfaceArea), HLL_TODO_EXPORT(Parts_SetPartsTextHighlight, GUIEngine_Parts_SetPartsTextHighlight), HLL_TODO_EXPORT(Parts_AddPartsTextHighlight, GUIEngine_Parts_AddPartsTextHighlight), HLL_TODO_EXPORT(Parts_ClearPartsTextHighlight, GUIEngine_Parts_ClearPartsTextHighlight), HLL_TODO_EXPORT(Parts_SetPartsTextCountReturn, GUIEngine_Parts_SetPartsTextCountReturn), HLL_TODO_EXPORT(Parts_GetPartsTextCountReturn, GUIEngine_Parts_GetPartsTextCountReturn), - HLL_TODO_EXPORT(Parts_SetFont, GUIEngine_Parts_SetFont), - HLL_TODO_EXPORT(Parts_SetPartsFontType, GUIEngine_Parts_SetPartsFontType), - HLL_TODO_EXPORT(Parts_SetPartsFontSize, GUIEngine_Parts_SetPartsFontSize), - HLL_TODO_EXPORT(Parts_SetPartsFontColor, GUIEngine_Parts_SetPartsFontColor), - HLL_TODO_EXPORT(Parts_SetPartsFontBoldWeight, GUIEngine_Parts_SetPartsFontBoldWeight), - HLL_TODO_EXPORT(Parts_SetPartsFontEdgeColor, GUIEngine_Parts_SetPartsFontEdgeColor), - HLL_TODO_EXPORT(Parts_SetPartsFontEdgeWeight, GUIEngine_Parts_SetPartsFontEdgeWeight), - HLL_TODO_EXPORT(Parts_SetTextCharSpace, GUIEngine_Parts_SetTextCharSpace), - HLL_TODO_EXPORT(Parts_SetTextLineSpace, GUIEngine_Parts_SetTextLineSpace), + HLL_EXPORT(Parts_SetFont, PE_SetFont), + HLL_EXPORT(Parts_SetPartsFontType, PE_SetPartsFontType), + HLL_EXPORT(Parts_SetPartsFontSize, PE_SetPartsFontSize), + HLL_EXPORT(Parts_SetPartsFontColor, PE_SetPartsFontColor), + HLL_EXPORT(Parts_SetPartsFontBoldWeight, PE_SetPartsFontBoldWeight), + HLL_EXPORT(Parts_SetPartsFontEdgeColor, PE_SetPartsFontEdgeColor), + HLL_EXPORT(Parts_SetPartsFontEdgeWeight, PE_SetPartsFontEdgeWeight), + HLL_EXPORT(Parts_SetTextCharSpace, PE_SetTextCharSpace), + HLL_EXPORT(Parts_SetTextLineSpace, PE_SetTextLineSpace), HLL_TODO_EXPORT(Parts_SetHGaugeCG, GUIEngine_Parts_SetHGaugeCG), HLL_TODO_EXPORT(Parts_SetHGaugeRate, GUIEngine_Parts_SetHGaugeRate), HLL_TODO_EXPORT(Parts_SetVGaugeCG, GUIEngine_Parts_SetVGaugeCG), HLL_TODO_EXPORT(Parts_SetVGaugeRate, GUIEngine_Parts_SetVGaugeRate), - HLL_TODO_EXPORT(Parts_SetHGaugeSurfaceArea, GUIEngine_Parts_SetHGaugeSurfaceArea), - HLL_TODO_EXPORT(Parts_SetVGaugeSurfaceArea, GUIEngine_Parts_SetVGaugeSurfaceArea), + HLL_EXPORT(Parts_SetHGaugeSurfaceArea, PE_SetHGaugeSurfaceArea), + HLL_EXPORT(Parts_SetVGaugeSurfaceArea, PE_SetVGaugeSurfaceArea), HLL_TODO_EXPORT(Parts_SetNumeralCG, GUIEngine_Parts_SetNumeralCG), HLL_TODO_EXPORT(Parts_SetNumeralLinkedCGNumberWidthWidthList, GUIEngine_Parts_SetNumeralLinkedCGNumberWidthWidthList), HLL_TODO_EXPORT(Parts_SetNumeralFont, GUIEngine_Parts_SetNumeralFont), @@ -843,7 +842,7 @@ HLL_LIBRARY(GUIEngine, HLL_TODO_EXPORT(Parts_SetNumeralShowComma, GUIEngine_Parts_SetNumeralShowComma), HLL_TODO_EXPORT(Parts_SetNumeralSpace, GUIEngine_Parts_SetNumeralSpace), HLL_TODO_EXPORT(Parts_SetNumeralLength, GUIEngine_Parts_SetNumeralLength), - HLL_TODO_EXPORT(Parts_SetNumeralSurfaceArea, GUIEngine_Parts_SetNumeralSurfaceArea), + HLL_EXPORT(Parts_SetNumeralSurfaceArea, PE_SetNumeralSurfaceArea), HLL_TODO_EXPORT(Parts_SetPartsRectangleDetectionSize, GUIEngine_Parts_SetPartsRectangleDetectionSize), HLL_TODO_EXPORT(Parts_SetPartsRectangleDetectionSurfaceArea, GUIEngine_Parts_SetPartsRectangleDetectionSurfaceArea), HLL_TODO_EXPORT(Parts_SetPartsCGDetectionSize, GUIEngine_Parts_SetPartsCGDetectionSize), @@ -879,7 +878,7 @@ HLL_LIBRARY(GUIEngine, HLL_EXPORT(Parts_BuildPartsConstructionProcess, PE_BuildPartsConstructionProcess), HLL_TODO_EXPORT(Parts_AddDrawTextToPartsConstructionProcess, GUIEngine_Parts_AddDrawTextToPartsConstructionProcess), HLL_TODO_EXPORT(Parts_AddCopyTextToPartsConstructionProcess, GUIEngine_Parts_AddCopyTextToPartsConstructionProcess), - HLL_TODO_EXPORT(Parts_SetPartsConstructionSurfaceArea, GUIEngine_Parts_SetPartsConstructionSurfaceArea), + HLL_EXPORT(Parts_SetPartsConstructionSurfaceArea, PE_SetPartsConstructionSurfaceArea), HLL_TODO_EXPORT(Parts_CreateParts3DLayerPluginID, GUIEngine_Parts_CreateParts3DLayerPluginID), HLL_TODO_EXPORT(Parts_GetParts3DLayerPluginID, GUIEngine_Parts_GetParts3DLayerPluginID), HLL_TODO_EXPORT(Parts_ReleaseParts3DLayerPluginID, GUIEngine_Parts_ReleaseParts3DLayerPluginID), diff --git a/src/parts/construction.c b/src/parts/construction.c index 951fa80..5da0a5c 100644 --- a/src/parts/construction.c +++ b/src/parts/construction.c @@ -102,8 +102,8 @@ static void build_cg(struct parts *parts, struct parts_construction_process *cpr { struct cg *cg = asset_cg_load(op->no); assert(cg); - gfx_delete_texture(&cproc->texture); - gfx_init_texture_with_cg(&cproc->texture, cg); + gfx_delete_texture(&cproc->common.texture); + gfx_init_texture_with_cg(&cproc->common.texture, cg); parts_set_cg_dims(parts, cg); parts_recalculate_pos(parts); cg_free(cg); @@ -112,7 +112,7 @@ static void build_cg(struct parts *parts, struct parts_construction_process *cpr static void build_fill_alpha_color(struct parts_construction_process *cproc, struct parts_cp_fill_alpha_color *op) { - gfx_fill_alpha_color(&cproc->texture, op->x, op->y, op->w, op->h, op->r, op->g, op->b, op->a); + gfx_fill_alpha_color(&cproc->common.texture, op->x, op->y, op->w, op->h, op->r, op->g, op->b, op->a); } bool PE_BuildPartsConstructionProcess(int parts_no, int state) @@ -139,4 +139,13 @@ bool PE_BuildPartsConstructionProcess(int parts_no, int state) bool PE_AddDrawTextToPartsConstructionProcess(int parts_no, int x, int y, struct string *text, int type, int size, int r, int g, int b, float bold_weight, int edge_r, int edge_g, int edge_b, float edge_weight, int char_space, int line_space, int state); bool PE_AddCopyTextToPartsConstructionProcess(int parts_no, int x, int y, struct string *text, int type, int size, int r, int g, int b, float bold_weight, int edge_r, int edge_g, int edge_b, float edge_weight, int char_space, int line_space, int state); -bool PE_SetPartsConstructionSurfaceArea(int parts_no, int x, int y, int w, int h, int state); + +bool PE_SetPartsConstructionSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) + return false; + + struct parts_construction_process *cproc = get_cproc(parts_no, state); + parts_set_surface_area(&cproc->common, x, y, w, h); + return true; +} diff --git a/src/parts/parts.c b/src/parts/parts.c index 586a7ad..8a3bbec 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -47,6 +47,7 @@ static void parts_init(struct parts *parts) parts->rotation.z = 0.0; TAILQ_INIT(&parts->children); TAILQ_INIT(&parts->motion); + gfx_font_init(); } static struct parts *parts_alloc(void) @@ -103,11 +104,11 @@ static void parts_state_free(struct parts_state *state) { switch (state->type) { case PARTS_CG: - gfx_delete_texture(&state->cg.texture); + gfx_delete_texture(&state->common.texture); break; case PARTS_TEXT: + gfx_delete_texture(&state->common.texture); free(state->text.lines); - gfx_delete_texture(&state->text.texture); break; case PARTS_ANIMATION: for (unsigned i = 0; i < state->anim.nr_frames; i++) { @@ -115,18 +116,18 @@ static void parts_state_free(struct parts_state *state) } break; case PARTS_NUMERAL: - gfx_delete_texture(&state->num.texture); + gfx_delete_texture(&state->common.texture); for (int i = 0; i < 12; i++) { gfx_delete_texture(&state->num.cg[i]); } break; case PARTS_HGAUGE: case PARTS_VGAUGE: - gfx_delete_texture(&state->gauge.texture); + gfx_delete_texture(&state->common.texture); gfx_delete_texture(&state->gauge.cg); break; case PARTS_CONSTRUCTION_PROCESS: - gfx_delete_texture(&state->cproc.texture); + gfx_delete_texture(&state->common.texture); while (!TAILQ_EMPTY(&state->cproc.ops)) { struct parts_cp_op *op = TAILQ_FIRST(&state->cproc.ops); TAILQ_REMOVE(&state->cproc.ops, op, entry); @@ -293,28 +294,11 @@ void parts_set_alpha(struct parts *parts, int alpha) parts->alpha = max(0, min(255, alpha)); for (int i = 0; i < PARTS_NR_STATES; i++) { struct parts_state *s = &parts->states[i]; - switch (s->type) { - case PARTS_CG: - s->cg.texture.alpha_mod = parts->alpha; - break; - case PARTS_TEXT: - s->text.texture.alpha_mod = parts->alpha; - break; - case PARTS_ANIMATION: + s->common.texture.alpha_mod = parts->alpha; + if (s->type == PARTS_ANIMATION) { for (unsigned i = 0; i < s->anim.nr_frames; i++) { s->anim.frames[i].alpha_mod = parts->alpha; } - break; - case PARTS_NUMERAL: - s->num.texture.alpha_mod = parts->alpha; - break; - case PARTS_HGAUGE: - case PARTS_VGAUGE: - s->gauge.texture.alpha_mod = parts->alpha; - break; - case PARTS_CONSTRUCTION_PROCESS: - s->cproc.texture.alpha_mod = parts->alpha; - break; } } parts_dirty(parts); @@ -335,8 +319,9 @@ static bool parts_set_cg(struct parts *parts, struct cg *cg, int cg_no, int stat if (!cg) return false; struct parts_cg *parts_cg = parts_get_cg(parts, state); - gfx_delete_texture(&parts_cg->texture); - gfx_init_texture_with_cg(&parts_cg->texture, cg); + gfx_delete_texture(&parts_cg->common.texture); + gfx_init_texture_with_cg(&parts_cg->common.texture, cg); + parts_cg->common.surface_area = (Rectangle) { 0, 0, cg->metrics.w, cg->metrics.h };; parts_cg->no = cg_no; parts_set_cg_dims(parts, cg); parts_recalculate_pos(parts); @@ -370,26 +355,26 @@ bool parts_set_cg_by_name(struct parts *parts, struct string *cg_name, int state void parts_set_hgauge_rate(struct parts *parts, float rate, int state) { struct parts_gauge *g = parts_get_hgauge(parts, state); - if (!g->texture.handle) { + if (!g->common.texture.handle) { WARNING("HGauge texture uninitialized"); return; } int pixels = rate * g->cg.w; - gfx_copy_with_alpha_map(&g->texture, 0, 0, &g->cg, 0, 0, pixels, g->cg.h); - gfx_fill_amap(&g->texture, pixels, 0, g->cg.w - pixels, g->cg.h, 0); + gfx_copy_with_alpha_map(&g->common.texture, 0, 0, &g->cg, 0, 0, pixels, g->cg.h); + gfx_fill_amap(&g->common.texture, pixels, 0, g->cg.w - pixels, g->cg.h, 0); parts_dirty(parts); } void parts_set_vgauge_rate(struct parts *parts, float rate, int state) { struct parts_gauge *g = parts_get_vgauge(parts, state); - if (!g->texture.handle) { + if (!g->common.texture.handle) { WARNING("VGauge texture uninitialized"); return; } int pixels = rate * g->cg.h; - gfx_copy_with_alpha_map(&g->texture, 0, pixels, &g->cg, 0, pixels, g->cg.w, g->cg.h - pixels); - gfx_fill_amap(&g->texture, 0, 0, g->cg.w, pixels, 0); + gfx_copy_with_alpha_map(&g->common.texture, 0, pixels, &g->cg, 0, pixels, g->cg.w, g->cg.h - pixels); + gfx_fill_amap(&g->common.texture, 0, 0, g->cg.w, pixels, 0); parts_dirty(parts); } @@ -445,15 +430,16 @@ bool parts_set_number(struct parts *parts, int n, int state) w += (nr_chars-1) * num->space; // copy chars to texture - gfx_delete_texture(&num->texture); - gfx_init_texture_rgba(&num->texture, w, h, (SDL_Color){0, 0, 0, 255}); + gfx_delete_texture(&num->common.texture); + gfx_init_texture_rgba(&num->common.texture, w, h, (SDL_Color){0, 0, 0, 255}); + num->common.surface_area = (Rectangle) { 0, 0, w, h }; int x = 0; for (int i = nr_chars-1; i>= 0; i--) { Texture *ch = &num->cg[chars[i]]; if (!ch->handle) continue; - gfx_copy_with_alpha_map(&num->texture, x, 0, ch, 0, 0, ch->w, ch->h); + gfx_copy_with_alpha_map(&num->common.texture, x, 0, ch, 0, 0, ch->w, ch->h); x += ch->w + num->space; } @@ -472,6 +458,17 @@ void parts_set_state(struct parts *parts, enum parts_state_type state) } } +void parts_set_surface_area(struct parts_common *common, int x, int y, int w, int h) +{ + if (!w && !h) { + x = 0; + y = 0; + w = common->texture.w; + h = common->texture.h; + } + common->surface_area = (Rectangle) { x, y, w, h }; +} + static void parts_update_loop(struct parts *parts, int passed_time) { if (parts->states[parts->state].type != PARTS_ANIMATION) @@ -488,7 +485,7 @@ static void parts_update_loop(struct parts *parts, int passed_time) if (frame_diff > 0) { anim->elapsed = remainder; anim->current_frame = (anim->current_frame + frame_diff) % anim->nr_frames; - anim->texture = anim->frames[anim->current_frame]; + anim->common.texture = anim->frames[anim->current_frame]; parts_dirty(parts); } else { anim->elapsed = elapsed; @@ -560,8 +557,7 @@ void PE_UpdateParts(int passed_time, possibly_unused bool is_skip, possibly_unus bool PE_SetPartsCG(int parts_no, struct string *cg_name, possibly_unused int sprite_deform, int state) { - state--; - if (state < 0 || state > 2) { + if (!parts_state_valid(--state)) { WARNING("Invalid parts state: %d", state); return false; } @@ -570,18 +566,28 @@ bool PE_SetPartsCG(int parts_no, struct string *cg_name, possibly_unused int spr bool PE_SetPartsCG_by_index(int parts_no, int cg_no, possibly_unused int sprite_deform, int state) { - state--; - if (state < 0 || state > 2) { + if (!parts_state_valid(--state)) { WARNING("Invalid parts state: %d", state); return false; } return parts_set_cg_by_index(parts_get(parts_no), cg_no, state); } +bool PE_SetPartsCGSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) { + WARNING("Invalid parts state: %d", state); + return false; + } + + struct parts_cg *cg = parts_get_cg(parts_get(parts_no), state); + parts_set_surface_area(&cg->common, x, y, w, h); + return true; +} + int PE_GetPartsCGNumber(int parts_no, int state) { - state--; - if (state < 0 || state > 2) { + if (!parts_state_valid(--state)) { WARNING("Invalid parts state: %d", state); return false; } @@ -591,8 +597,7 @@ int PE_GetPartsCGNumber(int parts_no, int state) bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_time, int state) { - state--; - if (state < 0 || state > 2) { + if (!parts_state_valid(--state)) { WARNING("Invalid parts state: %d", state); return false; } @@ -622,7 +627,20 @@ bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_tim anim->frame_time = frame_time; anim->elapsed = 0; anim->current_frame = 0; - anim->texture = frames[0]; + anim->common.texture = frames[0]; + anim->common.surface_area = parts->rect; + return true; +} + +bool PE_SetLoopCGSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) { + WARNING("Invalid parts state: %d", state); + return false; + } + + struct parts_animation *anim = parts_get_animation(parts_get(parts_no), state); + parts_set_surface_area(&anim->common, x, y, w, h); return true; } @@ -635,10 +653,11 @@ static bool set_gauge_cg(int parts_no, struct cg *cg, int state, bool vert) struct parts *parts = parts_get(parts_no); struct parts_gauge *g = vert ? parts_get_vgauge(parts, state) : parts_get_hgauge(parts, state); gfx_init_texture_with_cg(&g->cg, cg); - gfx_init_texture_with_cg(&g->texture, cg); + gfx_init_texture_with_cg(&g->common.texture, cg); - gfx_init_texture_rgba(&g->texture, g->cg.w, g->cg.h, (SDL_Color){0,0,0,255}); - gfx_copy_with_alpha_map(&g->texture, 0, 0, &g->cg, 0, 0, g->cg.w, g->cg.h); + gfx_init_texture_rgba(&g->common.texture, g->cg.w, g->cg.h, (SDL_Color){0,0,0,255}); + gfx_copy_with_alpha_map(&g->common.texture, 0, 0, &g->cg, 0, 0, g->cg.w, g->cg.h); + g->common.surface_area = (Rectangle) { 0, 0, g->cg.w, g->cg.h }; parts->rect.w = g->cg.w; parts->rect.h = g->cg.h; @@ -677,6 +696,16 @@ bool PE_SetHGaugeRate(int parts_no, int numerator, int denominator, int state) return true; } +bool PE_SetHGaugeSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) + return false; + + struct parts_gauge *g = parts_get_hgauge(parts_get(parts_no), state); + parts_set_surface_area(&g->common, x, y, w, h); + return true; +} + bool PE_SetVGaugeCG(int parts_no, struct string *cg_name, int state) { struct cg *cg = asset_cg_load_by_name(cg_name->text, NULL); @@ -707,6 +736,16 @@ bool PE_SetVGaugeRate(int parts_no, int numerator, int denominator, int state) return true; } +bool PE_SetVGaugeSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) + return false; + + struct parts_gauge *g = parts_get_vgauge(parts_get(parts_no), state); + parts_set_surface_area(&g->common, x, y, w, h); + return true; +} + bool PE_SetNumeralCG_by_index(int parts_no, int cg_no, int state) { state--; @@ -787,6 +826,16 @@ bool PE_SetNumeralSpace(int parts_no, int space, int state) return true; } +bool PE_SetNumeralSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) + return false; + + struct parts_numeral *n = parts_get_numeral(parts_get(parts_no), state); + parts_set_surface_area(&n->common, x, y, w, h); + return true; +} + bool PE_SetPartsRectangleDetectionSize(int PartsNumber, int Width, int Height, int State); bool PE_SetPartsFlash(int PartsNumber, struct string *pIFlashFileName, int State); bool PE_IsPartsFlashEnd(int PartsNumber, int State); diff --git a/src/parts/parts_internal.h b/src/parts/parts_internal.h index 77af863..cc81ea9 100644 --- a/src/parts/parts_internal.h +++ b/src/parts/parts_internal.h @@ -86,13 +86,18 @@ enum parts_type { PARTS_CONSTRUCTION_PROCESS, }; -struct parts_cg { +struct parts_common { Texture texture; + Rectangle surface_area; +}; + +struct parts_cg { + struct parts_common common; int no; }; struct parts_text { - Texture texture; + struct parts_common common; unsigned nr_lines; struct parts_text_line *lines; unsigned line_space; @@ -101,7 +106,7 @@ struct parts_text { }; struct parts_animation { - Texture texture; + struct parts_common common; unsigned cg_no; unsigned nr_frames; Texture *frames; @@ -111,7 +116,7 @@ struct parts_animation { }; struct parts_numeral { - Texture texture; + struct parts_common common; Texture cg[12]; int space; int show_comma; @@ -119,7 +124,7 @@ struct parts_numeral { }; struct parts_gauge { - Texture texture; + struct parts_common common; Texture cg; }; @@ -147,13 +152,14 @@ struct parts_cp_op { }; struct parts_construction_process { - Texture texture; + struct parts_common common; TAILQ_HEAD(, parts_cp_op) ops; }; struct parts_state { enum parts_type type; union { + struct parts_common common; struct parts_cg cg; struct parts_text text; struct parts_animation anim; @@ -218,6 +224,7 @@ bool parts_set_number(struct parts *parts, int n, int state); void parts_set_state(struct parts *parts, enum parts_state_type state); void parts_release(int parts_no); void parts_release_all(void); +void parts_set_surface_area(struct parts_common *common, int x, int y, int w, int h); // render.c void parts_render_init(void); diff --git a/src/parts/render.c b/src/parts/render.c index 597d1ff..0665faa 100644 --- a/src/parts/render.c +++ b/src/parts/render.c @@ -34,6 +34,13 @@ struct parts_render_params { uint8_t alpha; }; +static struct { + struct shader shader; + GLint alpha_mod; + GLint bot_left; + GLint top_right; +} parts_shader; + static void parts_render_text(struct parts *parts, struct parts_render_params *params) { parts_recalculate_offset(parts); @@ -43,10 +50,11 @@ static void parts_render_text(struct parts *parts, struct parts_render_params *p .w = parts->rect.w, .h = parts->rect.h }; - gfx_render_texture(&parts->states[parts->state].text.texture, &rect); + gfx_render_texture(&parts->states[parts->state].common.texture, &rect); } -static void parts_render_cg(struct parts *parts, Texture *t, struct parts_render_params *params) +static void parts_render_cg(struct parts *parts, struct parts_common *common, + struct parts_render_params *params) { parts_recalculate_offset(parts); @@ -62,14 +70,20 @@ static void parts_render_cg(struct parts *parts, Texture *t, struct parts_render mat4 wv_transform = WV_TRANSFORM(config.view_width, config.view_height); struct gfx_render_job job = { - .shader = NULL, // default shader - .texture = t->handle, + .shader = &parts_shader.shader, + .texture = common->texture.handle, .world_transform = mw_transform[0], .view_transform = wv_transform[0], - .data = t, + .data = &common->texture, }; - gfx_render(&job); + const Rectangle *r = &common->surface_area; + + gfx_prepare_job(&job); + glUniform1f(parts_shader.alpha_mod, common->texture.alpha_mod / 255.0); + glUniform2f(parts_shader.bot_left, r->x, r->y); + glUniform2f(parts_shader.top_right, r->x + r->w, r->y + r->h); + gfx_run_job(&job); } static void parts_render(struct parts *parts, struct parts_render_params *parent_params) @@ -91,33 +105,20 @@ static void parts_render(struct parts *parts, struct parts_render_params *parent // render struct parts_state *state = &parts->states[parts->state]; - switch (state->type) { - case PARTS_CG: - if (state->cg.texture.handle) - parts_render_cg(parts, &state->cg.texture, ¶ms); - break; - case PARTS_TEXT: - if (state->text.texture.handle) + if (state->common.texture.handle) { + switch (state->type) { + case PARTS_CG: + case PARTS_ANIMATION: + case PARTS_NUMERAL: + case PARTS_HGAUGE: + case PARTS_VGAUGE: + case PARTS_CONSTRUCTION_PROCESS: + parts_render_cg(parts, &state->common, ¶ms); + break; + case PARTS_TEXT: parts_render_text(parts, ¶ms); - break; - case PARTS_ANIMATION: - if (state->anim.texture.handle) - parts_render_cg(parts, &state->anim.texture, ¶ms); - break; - case PARTS_NUMERAL: - if (state->num.texture.handle) { - parts_render_cg(parts, &state->num.texture, ¶ms); + break; } - break; - case PARTS_HGAUGE: - case PARTS_VGAUGE: - if (state->gauge.texture.handle) - parts_render_cg(parts, &state->gauge.texture, ¶ms); - break; - case PARTS_CONSTRUCTION_PROCESS: - if (state->cproc.texture.handle) - parts_render_cg(parts, &state->cproc.texture, ¶ms); - break; } // render children @@ -157,4 +158,9 @@ void parts_render_init(void) goat_sprite.has_alpha = true; goat_sprite.render = parts_engine_render; scene_register_sprite(&goat_sprite); + + gfx_load_shader(&parts_shader.shader, "shaders/render.v.glsl", "shaders/parts.f.glsl"); + parts_shader.alpha_mod = glGetUniformLocation(parts_shader.shader.program, "alpha_mod"); + parts_shader.bot_left = glGetUniformLocation(parts_shader.shader.program, "bot_left"); + parts_shader.top_right = glGetUniformLocation(parts_shader.shader.program, "top_right"); } diff --git a/src/parts/text.c b/src/parts/text.c index a705e04..162d2d9 100644 --- a/src/parts/text.c +++ b/src/parts/text.c @@ -46,8 +46,8 @@ static void parts_text_append(struct parts *parts, struct string *text, int stat { struct parts_text *t = parts_get_text(parts, state); - if (!t->texture.handle) { - gfx_init_texture_rgba(&t->texture, config.view_width, config.view_height, + if (!t->common.texture.handle) { + gfx_init_texture_rgba(&t->common.texture, config.view_width, config.view_height, (SDL_Color){ 0, 0, 0, 0 }); } @@ -68,7 +68,7 @@ static void parts_text_append(struct parts *parts, struct string *text, int stat continue; } - t->cursor.x += gfx_render_text(&t->texture, t->cursor.x, t->cursor.y, c, &t->ts); + t->cursor.x += gfx_render_text(&t->common.texture, t->cursor.x, t->cursor.y, c, &t->ts); const unsigned old_height = t->lines[t->nr_lines-1].height; const unsigned new_height = t->ts.size; @@ -86,13 +86,12 @@ static void parts_text_clear(struct parts *parts, int state) text->nr_lines = 0; text->cursor.x = 0; text->cursor.y = 0; - gfx_delete_texture(&text->texture); + gfx_delete_texture(&text->common.texture); } bool PE_SetText(int parts_no, struct string *text, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; struct parts *parts = parts_get(parts_no); @@ -103,8 +102,7 @@ bool PE_SetText(int parts_no, struct string *text, int state) bool PE_AddPartsText(int parts_no, struct string *text, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; struct parts *parts = parts_get(parts_no); @@ -112,12 +110,21 @@ bool PE_AddPartsText(int parts_no, struct string *text, int state) return true; } +bool PE_SetPartsTextSurfaceArea(int parts_no, int x, int y, int w, int h, int state) +{ + if (!parts_state_valid(--state)) + return false; + + struct parts_text *text = parts_get_text(parts_get(parts_no), state); + parts_set_surface_area(&text->common, x, y, w, h); + return true; +} + //bool PE_DeletePartsTopTextLine(int PartsNumber, int State); bool PE_SetFont(int parts_no, int type, int size, int r, int g, int b, float bold_weight, int edge_r, int edge_g, int edge_b, float edge_weight, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; struct parts_text *text = parts_get_text(parts_get(parts_no), state); @@ -132,8 +139,7 @@ bool PE_SetFont(int parts_no, int type, int size, int r, int g, int b, float bol bool PE_SetPartsFontType(int parts_no, int type, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->ts.face = type; @@ -142,8 +148,7 @@ bool PE_SetPartsFontType(int parts_no, int type, int state) bool PE_SetPartsFontSize(int parts_no, int size, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->ts.size = size; @@ -152,8 +157,7 @@ bool PE_SetPartsFontSize(int parts_no, int size, int state) bool PE_SetPartsFontColor(int parts_no, int r, int g, int b, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->ts.color = (SDL_Color) { r, g, b, 255 }; @@ -162,8 +166,7 @@ bool PE_SetPartsFontColor(int parts_no, int r, int g, int b, int state) bool PE_SetPartsFontBoldWeight(int parts_no, float bold_weight, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->ts.weight = bold_weight * 1000; @@ -172,8 +175,7 @@ bool PE_SetPartsFontBoldWeight(int parts_no, float bold_weight, int state) bool PE_SetPartsFontEdgeColor(int parts_no, int r, int g, int b, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->ts.edge_color = (SDL_Color) { r, g, b, 255 }; @@ -182,8 +184,7 @@ bool PE_SetPartsFontEdgeColor(int parts_no, int r, int g, int b, int state) bool PE_SetPartsFontEdgeWeight(int parts_no, float edge_weight, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; struct parts_text *text = parts_get_text(parts_get(parts_no), state); @@ -193,8 +194,7 @@ bool PE_SetPartsFontEdgeWeight(int parts_no, float edge_weight, int state) bool PE_SetTextCharSpace(int parts_no, int char_space, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->ts.font_spacing = char_space; @@ -203,8 +203,7 @@ bool PE_SetTextCharSpace(int parts_no, int char_space, int state) bool PE_SetTextLineSpace(int parts_no, int line_space, int state) { - state--; - if (state < 0 || state >= PARTS_NR_STATES) + if (!parts_state_valid(--state)) return false; parts_get_text(parts_get(parts_no), state)->line_space = line_space; diff --git a/src/text.c b/src/text.c index 160c88a..7476a7a 100644 --- a/src/text.c +++ b/src/text.c @@ -67,8 +67,12 @@ static struct font *load_font(enum font_face type) ERROR("Failed to load %s font", type == FONT_GOTHIC ? "gothic" : "mincho"); } +static bool font_initialized = false; + void gfx_font_init(void) { + if (font_initialized) + return; if (config.fnl_path) { struct fnl *fnl = fnl_open(config.fnl_path); if (!fnl) @@ -83,6 +87,7 @@ void gfx_font_init(void) fonts[FONT_GOTHIC] = load_font(FONT_GOTHIC); fonts[FONT_MINCHO] = load_font(FONT_MINCHO); } + font_initialized = true; } static unsigned get_face(unsigned face)