Skip to content
Snippets Groups Projects
Select Git revision
  • e15ffd2bc8a76ede6ce15973b52ba78bc6bd17ca
  • next default protected
  • next-test
  • classic-netcode-fixes
  • fix-dedi-pthread
  • fix-enemy-target
  • master protected
  • better-distance-math
  • movie
  • softcode-info
  • acs
  • clipmidtex
  • custom-map-names
  • nogravity-trampolines
  • 2214-pre4
  • 2214-pre3
  • just-in-case
  • fix-opengl-parameter-crash
  • 2214-pre2
  • 2214-pre1
  • delfile2
  • SRB2_release_2.2.15
  • SRB2_release_2.2.13
  • SRB2_release_2.2.12
  • SRB2_release_2.2.11
  • SRB2_release_2.2.10
  • SRB2_release_2.2.9
  • SRB2_release_2.2.8
  • SRB2_release_2.2.7
  • SRB2_release_2.2.6
  • SRB2_release_2.2.5
  • SRB2_release_2.2.4
  • SRB2_release_2.2.3
  • SRB2_release_2.2.2
  • SRB2_release_2.2.1
  • SRB2_release_2.2.0
  • SRB2_release_2.1.25
  • SRB2_release_2.1.24
  • SRB2_release_2.1.23
  • SRB2_release_2.1.22
  • SRB2_release_2.1.21
41 results

apng.c

Blame
  • lua_hudlib_drawlist.c 14.02 KiB
    // SONIC ROBO BLAST 2
    //-----------------------------------------------------------------------------
    // Copyright (C) 2014-2016 by John "JTE" Muniz.
    // Copyright (C) 2014-2024 by Sonic Team Junior.
    //
    // This program is free software distributed under the
    // terms of the GNU General Public License, version 2.
    // See the 'LICENSE' file for more details.
    //-----------------------------------------------------------------------------
    /// \file  lua_hudlib_drawlist.c
    /// \brief a data structure for managing cached drawlists for the Lua hud lib
    
    #include "lua_hudlib_drawlist.h"
    
    #include <string.h>
    
    #include "v_video.h"
    #include "z_zone.h"
    
    enum drawitem_e {
    	DI_Draw = 0,
    	DI_DrawScaled,
    	DI_DrawStretched,
    	DI_DrawCropped,
    	DI_DrawNum,
    	DI_DrawPaddedNum,
    	DI_DrawFill,
    	DI_DrawFixedFill,
    	DI_DrawString,
    	DI_DrawNameTag,
    	DI_DrawScaledNameTag,
    	DI_DrawLevelTitle,
    	DI_FadeScreen,
    	DI_MAX,
    };
    
    // A single draw item with all possible arguments needed for a draw call.
    typedef struct drawitem_s {
    	enum drawitem_e type;
    	fixed_t x;
    	fixed_t y;
    	fixed_t w;
    	fixed_t h;
    	INT32 c;
    	fixed_t scale;
    	fixed_t hscale;
    	fixed_t vscale;
    	patch_t *patch;
    	INT32 flags;
    	UINT16 basecolor;
    	UINT16 outlinecolor;
    	UINT8 *colormap;
    	UINT8 *basecolormap;
    	UINT8 *outlinecolormap;
    	fixed_t sx;
    	fixed_t sy;
    	INT32 num;
    	INT32 digits;
    	const char *str;
    	UINT16 color;
    	UINT8 strength;
    	INT32 align;
    } drawitem_t;
    
    // The internal structure of a drawlist.
    struct huddrawlist_s {
    	drawitem_t *items;
    	size_t items_capacity;
    	size_t items_len;
    	char *strbuf;
    	size_t strbuf_capacity;
    	size_t strbuf_len;
    };
    
    // alignment types for v.drawString
    enum align {
    	align_left = 0,
    	align_center,
    	align_right,
    	align_fixed,
    	align_fixedcenter,
    	align_fixedright,
    	align_small,
    	align_smallfixed,
    	align_smallfixedcenter,
    	align_smallfixedright,
    	align_smallcenter,
    	align_smallright,
    	align_smallthin,
    	align_smallthincenter,
    	align_smallthinright,
    	align_smallthinfixed,
    	align_smallthinfixedcenter,
    	align_smallthinfixedright,
    	align_thin,
    	align_thinfixed,
    	align_thinfixedcenter,
    	align_thinfixedright,
    	align_thincenter,
    	align_thinright
    };
    
    huddrawlist_h LUA_HUD_CreateDrawList(void)
    {
    	huddrawlist_h drawlist;
    
    	drawlist = (huddrawlist_h) Z_Calloc(sizeof(struct huddrawlist_s), PU_STATIC, NULL);
    	drawlist->items = NULL;
    	drawlist->items_capacity = 0;
    	drawlist->items_len = 0;
    	drawlist->strbuf = NULL;
    	drawlist->strbuf_capacity = 0;
    	drawlist->strbuf_len = 0;
    
    	return drawlist;
    }
    
    void LUA_HUD_ClearDrawList(huddrawlist_h list)
    {
    	// rather than deallocate, we'll just save the existing allocation and empty
    	// it out for reuse
    
    	// this memset probably isn't necessary
    	if (list->items)
    	{
    		memset(list->items, 0, sizeof(drawitem_t) * list->items_capacity);
    	}
    
    	list->items_len = 0;
    
    	if (list->strbuf)
    	{
    		list->strbuf[0] = 0;
    	}
    	list->strbuf_len = 0;
    }
    
    void LUA_HUD_DestroyDrawList(huddrawlist_h list)
    {
    	if (list == NULL) return;
    
    	if (list->items)
    	{
    		Z_Free(list->items);
    	}
    	Z_Free(list);
    }
    
    boolean LUA_HUD_IsDrawListValid(huddrawlist_h list)
    {
    	if (!list) return false;
    
    	// that's all we can really do to check the validity of the handle right now
    	return true;
    }
    
    static size_t AllocateDrawItem(huddrawlist_h list)
    {
    	if (!list) I_Error("can't allocate draw item: invalid list");
    	if (list->items_capacity <= list->items_len + 1)
    	{
    		if (list->items_capacity == 0) list->items_capacity = 128;
    		else list->items_capacity *= 2;
    		list->items = (drawitem_t *) Z_Realloc(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL);
    	}
    
    	return list->items_len++;
    }
    
    // copy string to list's internal string buffer
    // lua can deallocate the string before we get to use it, so it's important to
    // keep our own copy
    static const char *CopyString(huddrawlist_h list, const char* str)
    {
    	size_t lenstr;
    
    	if (!list) I_Error("can't allocate string; invalid list");
    	lenstr = strlen(str);
    	if (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
    	{
    		const char *old_offset = list->strbuf;
    		size_t i;
    		if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
    		while (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
    			list->strbuf_capacity *= 2;
    		list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
    
    		// align the string pointers to make sure old pointers don't point towards invalid addresses
    		// this is necessary since Z_ReallocAlign might actually move the string buffer in memory
    		for (i = 0; i < list->items_len; i++)
    		{
    			list->items[i].str += list->strbuf - old_offset;
    		}
    	}
    	const char *result = (const char *) &list->strbuf[list->strbuf_len];
    	strncpy(&list->strbuf[list->strbuf_len], str, lenstr + 1);
    	list->strbuf_len += lenstr + 1;
    	return result;
    }
    
    void LUA_HUD_AddDraw(
    	huddrawlist_h list,
    	INT32 x,
    	INT32 y,
    	patch_t *patch,
    	INT32 flags,
    	UINT8 *colormap
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_Draw;
    	item->x = x;
    	item->y = y;
    	item->patch = patch;
    	item->flags = flags;
    	item->colormap = colormap;
    }
    
    void LUA_HUD_AddDrawScaled(
    	huddrawlist_h list,
    	fixed_t x,
    	fixed_t y,
    	fixed_t scale,
    	patch_t *patch,
    	INT32 flags,
    	UINT8 *colormap
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawScaled;
    	item->x = x;
    	item->y = y;
    	item->scale = scale;
    	item->patch = patch;
    	item->flags = flags;
    	item->colormap = colormap;
    }
    
    void LUA_HUD_AddDrawStretched(
    	huddrawlist_h list,
    	fixed_t x,
    	fixed_t y,
    	fixed_t hscale,
    	fixed_t vscale,
    	patch_t *patch,
    	INT32 flags,
    	UINT8 *colormap
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawStretched;
    	item->x = x;
    	item->y = y;
    	item->hscale = hscale;
    	item->vscale = vscale;
    	item->patch = patch;
    	item->flags = flags;
    	item->colormap = colormap;
    }
    
    void LUA_HUD_AddDrawCropped(
    	huddrawlist_h list,
    	fixed_t x,
    	fixed_t y,
    	fixed_t hscale,
    	fixed_t vscale,
    	patch_t *patch,
    	INT32 flags,
    	UINT8 *colormap,
    	fixed_t sx,
    	fixed_t sy,
    	fixed_t w,
    	fixed_t h
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawCropped;
    	item->x = x;
    	item->y = y;
    	item->hscale = hscale;
    	item->vscale = vscale;
    	item->patch = patch;
    	item->flags = flags;
    	item->colormap = colormap;
    	item->sx = sx;
    	item->sy = sy;
    	item->w = w;
    	item->h = h;
    }
    
    void LUA_HUD_AddDrawNum(
    	huddrawlist_h list,
    	INT32 x,
    	INT32 y,
    	INT32 num,
    	INT32 flags
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawNum;
    	item->x = x;
    	item->y = y;
    	item->num = num;
    	item->flags = flags;
    }
    
    void LUA_HUD_AddDrawPaddedNum(
    	huddrawlist_h list,
    	INT32 x,
    	INT32 y,
    	INT32 num,
    	INT32 digits,
    	INT32 flags
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawPaddedNum;
    	item->x = x;
    	item->y = y;
    	item->num = num;
    	item->digits = digits;
    	item->flags = flags;
    }
    
    void LUA_HUD_AddDrawFill(
    	huddrawlist_h list,
    	INT32 x,
    	INT32 y,
    	INT32 w,
    	INT32 h,
    	INT32 c
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawFill;
    	item->x = x;
    	item->y = y;
    	item->w = w;
    	item->h = h;
    	item->c = c;
    }
    
    void LUA_HUD_AddDrawFixedFill(
    	huddrawlist_h list,
    	fixed_t x,
    	fixed_t y,
    	fixed_t w,
    	fixed_t h,
    	INT32 c
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawFixedFill;
    	item->x = x;
    	item->y = y;
    	item->w = w;
    	item->h = h;
    	item->c = c;
    }
    
    void LUA_HUD_AddDrawString(
    	huddrawlist_h list,
    	fixed_t x,
    	fixed_t y,
    	const char *str,
    	INT32 flags,
    	INT32 align
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawString;
    	item->x = x;
    	item->y = y;
    	item->str = CopyString(list, str);
    	item->flags = flags;
    	item->align = align;
    }
    
    void LUA_HUD_AddDrawNameTag(
    	huddrawlist_h list,
    	INT32 x,
    	INT32 y,
    	const char *str,
    	INT32 flags,
    	UINT16 basecolor,
    	UINT16 outlinecolor,
    	UINT8 *basecolormap,
    	UINT8 *outlinecolormap
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawNameTag;
    	item->x = x;
    	item->y = y;
    	item->str = CopyString(list, str);
    	item->flags = flags;
    	item->basecolor = basecolor;
    	item->outlinecolor = outlinecolor;
    	item->basecolormap = basecolormap;
    	item->outlinecolormap = outlinecolormap;
    }
    
    void LUA_HUD_AddDrawScaledNameTag(
    	huddrawlist_h list,
    	fixed_t x,
    	fixed_t y,
    	const char *str,
    	INT32 flags,
    	fixed_t scale,
    	UINT16 basecolor,
    	UINT16 outlinecolor,
    	UINT8 *basecolormap,
    	UINT8 *outlinecolormap
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawScaledNameTag;
    	item->x = x;
    	item->y = y;
    	item->str = CopyString(list, str);
    	item->flags = flags;
    	item->scale = scale;
    	item->basecolor = basecolor;
    	item->outlinecolor = outlinecolor;
    	item->basecolormap = basecolormap;
    	item->outlinecolormap = outlinecolormap;
    }
    
    void LUA_HUD_AddDrawLevelTitle(
    	huddrawlist_h list,
    	INT32 x,
    	INT32 y,
    	const char *str,
    	INT32 flags
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_DrawLevelTitle;
    	item->x = x;
    	item->y = y;
    	item->str = CopyString(list, str);
    	item->flags = flags;
    }
    
    void LUA_HUD_AddFadeScreen(
    	huddrawlist_h list,
    	UINT16 color,
    	UINT8 strength
    )
    {
    	size_t i = AllocateDrawItem(list);
    	drawitem_t *item = &list->items[i];
    	item->type = DI_FadeScreen;
    	item->color = color;
    	item->strength = strength;
    }
    
    void LUA_HUD_DrawList(huddrawlist_h list)
    {
    	size_t i;
    
    	if (!list) I_Error("HUD drawlist invalid");
    	if (list->items_len <= 0) return;
    	if (!list->items) I_Error("HUD drawlist->items invalid");
    
    	for (i = 0; i < list->items_len; i++)
    	{
    		drawitem_t *item = &list->items[i];
    
    		switch (item->type)
    		{
    			case DI_Draw:
    				V_DrawFixedPatch(item->x<<FRACBITS, item->y<<FRACBITS, FRACUNIT, item->flags, item->patch, item->colormap);
    				break;
    			case DI_DrawScaled:
    				V_DrawFixedPatch(item->x, item->y, item->scale, item->flags, item->patch, item->colormap);
    				break;
    			case DI_DrawStretched:
    				V_DrawStretchyFixedPatch(item->x, item->y, item->hscale, item->vscale, item->flags, item->patch, item->colormap);
    				break;
    			case DI_DrawCropped:
    				V_DrawCroppedPatch(item->x, item->y, item->hscale, item->vscale, item->flags, item->patch, item->colormap, item->sx, item->sy, item->w, item->h);
    				break;
    			case DI_DrawNum:
    				V_DrawTallNum(item->x, item->y, item->flags, item->num);
    				break;
    			case DI_DrawPaddedNum:
    				V_DrawPaddedTallNum(item->x, item->y, item->flags, item->num, item->digits);
    				break;
    			case DI_DrawFill:
    				V_DrawFill(item->x, item->y, item->w, item->h, item->c);
    				break;
    			case DI_DrawFixedFill:
    				V_DrawFixedFill(item->x, item->y, item->w, item->h, item->c);
    				break;
    			case DI_DrawString:
    				switch(item->align)
    				{
    				// hu_font
    				case align_left:
    					V_DrawString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_center:
    					V_DrawCenteredString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_right:
    					V_DrawRightAlignedString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_fixed:
    					V_DrawStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_fixedcenter:
    					V_DrawCenteredStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_fixedright:
    					V_DrawRightAlignedStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				// hu_font, 0.5x scale
    				case align_small:
    					V_DrawSmallString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallfixed:
    					V_DrawSmallStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallfixedcenter:
    					V_DrawCenteredSmallStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallfixedright:
    					V_DrawRightAlignedSmallStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallcenter:
    					V_DrawCenteredSmallString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallright:
    					V_DrawRightAlignedSmallString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallthin:
    					V_DrawSmallThinString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallthincenter:
    					V_DrawCenteredSmallThinString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallthinright:
    					V_DrawRightAlignedSmallThinString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallthinfixed:
    					V_DrawSmallThinStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallthinfixedcenter:
    					V_DrawCenteredSmallThinStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_smallthinfixedright:
    					V_DrawRightAlignedSmallThinStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				// tny_font
    				case align_thin:
    					V_DrawThinString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_thincenter:
    					V_DrawCenteredThinString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_thinright:
    					V_DrawRightAlignedThinString(item->x, item->y, item->flags, item->str);
    					break;
    				case align_thinfixed:
    					V_DrawThinStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_thinfixedcenter:
    					V_DrawCenteredThinStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				case align_thinfixedright:
    					V_DrawRightAlignedThinStringAtFixed(item->x, item->y, item->flags, item->str);
    					break;
    				}
    				break;
    			case DI_DrawNameTag:
    				V_DrawNameTag(item->x, item->y, item->flags, FRACUNIT, item->basecolormap, item->outlinecolormap, item->str);
    				break;
    			case DI_DrawScaledNameTag:
    				V_DrawNameTag(FixedInt(item->x), FixedInt(item->y), item->flags, item->scale, item->basecolormap, item->outlinecolormap, item->str);
    				break;
    			case DI_DrawLevelTitle:
    				V_DrawLevelTitle(item->x, item->y, item->flags, item->str);
    				break;
    			case DI_FadeScreen:
    				V_DrawFadeScreen(item->color, item->strength);
    				break;
    			default:
    				I_Error("can't draw draw list item: invalid draw list item type");
    				continue;
    		}
    	}
    }