Пример #1
0
static int l_font_draw_tooltip(lua_State *L)
{
    THFont* pFont = luaT_testuserdata<THFont>(L);
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L, 2);
    size_t iMsgLen;
    const char* sMsg = luaT_checkstring(L, 3, &iMsgLen);
    int iX = static_cast<int>(luaL_checkinteger(L, 4));
    int iY = static_cast<int>(luaL_checkinteger(L, 5));
    int iScreenWidth = pCanvas->getWidth();

    int iW = 200; // (for now) hardcoded width of tooltips
    uint32_t iBlack = pCanvas->mapColour(0x00, 0x00, 0x00);
    uint32_t iWhite = pCanvas->mapColour(0xFF, 0xFF, 0xFF);
    THFontDrawArea oArea = pFont->drawTextWrapped(nullptr, sMsg, iMsgLen, iX + 2, iY + 1, iW - 4, INT_MAX, 0);
    int iLastX = iX + oArea.iWidth + 3;
    int iFirstY = iY - (oArea.iEndY - iY) - 1;

    int iXOffset = iLastX > iScreenWidth ? iScreenWidth - iLastX : 0;
    int iYOffset = iFirstY < 0 ? -iFirstY : 0;

    pCanvas->fillRect(iBlack, iX + iXOffset, iFirstY + iYOffset, oArea.iWidth + 3, oArea.iEndY - iY + 2);
    pCanvas->fillRect(iWhite, iX + iXOffset + 1, iFirstY + 1 + iYOffset, oArea.iWidth + 1, oArea.iEndY - iY);

    pFont->drawTextWrapped(pCanvas, sMsg, iMsgLen, iX + 2 + iXOffset, iFirstY + 1 + iYOffset, iW - 4);

    lua_pushinteger(L, oArea.iEndY);

    return 1;
}
Пример #2
0
static int l_surface_destroy(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    pCanvas->endFrame();
    pCanvas->destroy();
    return 1;
}
Пример #3
0
static int l_surface_set_caption(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    pCanvas->setCaption(luaL_checkstring(L, 2));

    lua_settop(L, 1);
    return 1;
}
Пример #4
0
static int l_surface_map(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    lua_pushnumber(L, (lua_Number)pCanvas->mapColour(
        (Uint8)luaL_checkinteger(L, 2),
        (Uint8)luaL_checkinteger(L, 3),
        (Uint8)luaL_checkinteger(L, 4)));
    return 1;
}
Пример #5
0
static int l_surface_nonoverlapping(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    if(lua_isnone(L, 2) || lua_toboolean(L, 2) != 0)
        pCanvas->startNonOverlapping();
    else
        pCanvas->finishNonOverlapping();
    lua_settop(L, 1);
    return 1;
}
Пример #6
0
static int l_surface_end_frame(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    lua_settop(L, 1);
    if(pCanvas->endFrame())
        return 1;
    lua_pushnil(L);
    lua_pushstring(L, pCanvas->getLastError());
    return 2;
}
Пример #7
0
static int l_surface_get_clip(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    THClipRect rcClip;
    pCanvas->getClipRect(&rcClip);
    lua_pushinteger(L, rcClip.x);
    lua_pushinteger(L, rcClip.y);
    lua_pushinteger(L, rcClip.w);
    lua_pushinteger(L, rcClip.h);
    return 4;
}
Пример #8
0
static int l_surface_screenshot(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    const char *sFile = luaL_checkstring(L, 2);
    if(pCanvas->takeScreenshot(sFile))
    {
        lua_settop(L, 1);
        return 1;
    }
    lua_pushnil(L);
    lua_pushstring(L, pCanvas->getLastError());
    return 2;
}
Пример #9
0
static int l_surface_update(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    THRenderTargetCreationParams oParams = l_surface_creation_params(L, 2);
    if(pCanvas->update(&oParams))
    {
        lua_pushnil(L);
        return 1;
    }

    lua_pushstring(L, pCanvas->getLastError());
    return 1;
}
Пример #10
0
static int l_surface_new(lua_State *L)
{
    lua_remove(L, 1); // Value inserted by __call

    THRenderTargetCreationParams oParams = l_surface_creation_params(L, 1);
    THRenderTarget* pCanvas = luaT_stdnew<THRenderTarget>(L);
    if(pCanvas->create(&oParams))
        return 1;

    lua_pushnil(L);
    lua_pushstring(L, pCanvas->getLastError());
    return 2;
}
Пример #11
0
static int l_surface_rect(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    if(pCanvas->fillRect(static_cast<uint32_t>(luaL_checkinteger(L, 2)),
        static_cast<int>(luaL_checkinteger(L, 3)), static_cast<int>(luaL_checkinteger(L, 4)), static_cast<int>(luaL_checkinteger(L, 5)),
        static_cast<int>(luaL_checkinteger(L, 6))))
    {
        lua_settop(L, 1);
        return 1;
    }
    lua_pushnil(L);
    lua_pushstring(L, pCanvas->getLastError());
    return 2;
}
Пример #12
0
static int l_surface_set_clip(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    THClipRect rcClip;
    rcClip.x = static_cast<THClipRect::xy_t>(luaL_checkinteger(L, 2));
    rcClip.y = static_cast<THClipRect::xy_t>(luaL_checkinteger(L, 3));
    rcClip.w = static_cast<THClipRect::wh_t>(luaL_checkinteger(L, 4));
    rcClip.h = static_cast<THClipRect::wh_t>(luaL_checkinteger(L, 5));
    if(lua_toboolean(L, 6) != 0)
    {
        THClipRect rcExistingClip;
        pCanvas->getClipRect(&rcExistingClip);
        IntersectTHClipRect(rcClip, rcExistingClip);
    }
    pCanvas->setClipRect(&rcClip);
    lua_settop(L, 1);
    return 1;
}
Пример #13
0
static int l_surface_scale(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    THScaledItems eToScale = THSI_None;
    if(lua_isnoneornil(L, 3))
    {
        eToScale = THSI_All;
    }
    else
    {
        size_t iLength;
        const char* sOption = lua_tolstring(L, 3, &iLength);
        if(sOption && iLength >= 6 && std::memcmp(sOption, "bitmap", 6) == 0)
        {
            eToScale = THSI_Bitmaps;
        }
        else
            luaL_error(L, "Expected \"bitmap\" as 2nd argument");
    }
    lua_pushboolean(L, pCanvas->setScaleFactor(static_cast<float>(
        luaL_checknumber(L, 2)), eToScale) ? 1 : 0);
    return 1;
}
Пример #14
0
static int l_surface_new(lua_State *L)
{
    lua_remove(L, 1); // Value inserted by __call

    THRenderTargetCreationParams oParams;
    oParams.iWidth = luaL_checkint(L, 1);
    oParams.iHeight = luaL_checkint(L, 2);
    int iArg = 3;
    if(lua_type(L, iArg) == LUA_TNUMBER)
        oParams.iBPP = luaL_checkint(L, iArg++);
    else
        oParams.iBPP = 0;
    oParams.iSDLFlags = 0;
    oParams.bHardware = false;
    oParams.bDoubleBuffered = false;
    oParams.bFullscreen = false;
    oParams.bPresentImmediate = false;
    oParams.bReuseContext = false;
    oParams.bOpenGL = false;

#define FLAG(name, field, flag) \
    else if(stricmp(sOption, name) == 0) \
        oParams.field = true, oParams.iSDLFlags |= flag

    for(int iArgCount = lua_gettop(L); iArg <= iArgCount; ++iArg)
    {
        const char* sOption = luaL_checkstring(L, iArg);
        if(sOption[0] == 0)
            continue;
        FLAG("hardware"         , bHardware        , SDL_HWSURFACE );
        FLAG("doublebuf"        , bDoubleBuffered  , SDL_DOUBLEBUF );
        FLAG("fullscreen"       , bFullscreen      , SDL_FULLSCREEN);
        FLAG("present immediate", bPresentImmediate, 0             );
        FLAG("reuse context"    , bReuseContext    , 0             );
        FLAG("opengl"           , bOpenGL          , SDL_OPENGL    );
    }

#undef FLAG

#ifndef CORSIX_TH_USE_DX9_RENDERER
    if(SDL_WasInit(SDL_INIT_VIDEO))
    {
        char *sTitle, *sIcon;
        char *sTitle2 = NULL, *sIcon2 = NULL;
        size_t iLen;
        SDL_WM_GetCaption(&sTitle, &sIcon);
        if(sTitle)
        {
            iLen = strlen(sTitle) + 1;
            sTitle2 = (char*)malloc(iLen);
            memcpy(sTitle2, sTitle, iLen);
        }

        if(sIcon)
        {
            iLen = strlen(sIcon) + 1;
            sIcon2 = (char*)malloc(iLen);
            memcpy(sIcon2, sIcon, iLen);
        }

        SDL_QuitSubSystem(SDL_INIT_VIDEO);
        SDL_InitSubSystem(SDL_INIT_VIDEO);
        SDL_WM_SetCaption(sTitle2, sIcon2);

        free(sTitle2);
        free(sIcon2);
    }
#endif

    THRenderTarget* pCanvas = luaT_stdnew<THRenderTarget>(L);
    if(pCanvas->create(&oParams))
        return 1;

    lua_pushnil(L);
    lua_pushstring(L, pCanvas->getLastError());
    return 2;
}
Пример #15
0
static int l_town_map_draw(lua_State *L)
{
    luaL_checktype(L, 1, LUA_TTABLE);
    THMap *pMap = luaT_testuserdata<THMap>(L, 2);
    THRenderTarget *pCanvas = luaT_testuserdata<THRenderTarget>(L, 3);
    int iCanvasXBase = luaL_checkint(L, 4);
    int iCanvasYBase = luaL_checkint(L, 5);
    bool bShowHeat = lua_toboolean(L, 6) != 0;

    uint32_t iColourMyHosp = pCanvas->mapColour(0, 0, 70);
    uint32_t iColourWall = pCanvas->mapColour(255, 255, 255);
    uint32_t iColourDoor = pCanvas->mapColour(200, 200, 200);
    uint32_t iColourPurchasable = pCanvas->mapColour(255, 0, 0);

    const THMapNode *pNode = pMap->getNodeUnchecked(0, 0);
    const THMapNode *pOriginalNode = pMap->getOriginalNodeUnchecked(0, 0);
    int iCanvasY = iCanvasYBase + 3;
    for(int iY = 0; iY < pMap->getHeight(); ++iY, iCanvasY += 3)
    {
        int iCanvasX = iCanvasXBase;
        for(int iX = 0; iX < pMap->getWidth(); ++iX, ++pNode, ++pOriginalNode, iCanvasX += 3)
        {
            if(pOriginalNode->iFlags & THMN_Hospital)
            {
                uint32_t iColour = iColourMyHosp;
                if(!(pNode->iFlags & THMN_Hospital))
                {
                    // TODO: Replace 1 with player number
                    if(pMap->isParcelPurchasable(pNode->iParcelId, 1))
                        iColour = iColourPurchasable;
                    else
                        goto dont_paint_tile;
                }
                else if(bShowHeat)
                {
                    uint16_t iTemp = pMap->getNodeTemperature(pNode);
                    if(iTemp < 5200) // Less than 4 degrees
                        iTemp = 0;
                    else if(iTemp > 32767) // More than 25 degrees
                        iTemp = 255;
                    else // NB: 108 == (32767 - 5200) / 255
                        iTemp = (iTemp - 5200) / 108;
                    iColour = pCanvas->mapColour(static_cast<uint8_t>(iTemp), 0, 70);
                }
                pCanvas->fillRect(iColour, iCanvasX, iCanvasY, 3, 3);
            }
            dont_paint_tile:
#define IsWall(blk) ((82 <= ((blk) & 0xFF)) && (((blk) & 0xFF) <= 164))
#define IsWallDrawn(n) pMap->getNodeOwner(pNode) != 0 ? \
    IsWall(pNode->iBlock[n]) : IsWall(pOriginalNode->iBlock[n])
            if(IsWallDrawn(1))
                pCanvas->fillRect(iColourWall, iCanvasX, iCanvasY, 3, 1);
            if(IsWallDrawn(2))
                pCanvas->fillRect(iColourWall, iCanvasX, iCanvasY, 1, 3);
#undef IsWallDrawn
#undef IsWall
            if(pNode->iFlags & THMN_DoorNorth)
                pCanvas->fillRect(iColourDoor, iCanvasX, iCanvasY - 2, 2, 3);
            if(pNode->iFlags & THMN_DoorWest)
                pCanvas->fillRect(iColourDoor, iCanvasX - 3, iCanvasY, 3, 2);
        }
    }

    return 0;
}
Пример #16
0
static int l_surface_set_blue_filter_active(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    pCanvas->setBlueFilterActive((lua_isnoneornil(L, 2) != 0) ? false : (lua_toboolean(L, 2) != 0));
    return 1;
}
Пример #17
0
static int l_surface_get_renderer_details(lua_State *L)
{
    THRenderTarget* pCanvas = luaT_testuserdata<THRenderTarget>(L);
    lua_pushstring(L, pCanvas->getRendererDetails());
    return 1;
}
Пример #18
0
static int l_town_map_draw(lua_State *L)
{
    luaL_checktype(L, 1, LUA_TTABLE);
    THMap *pMap = luaT_testuserdata<THMap>(L, 2);
    THRenderTarget *pCanvas = luaT_testuserdata<THRenderTarget>(L, 3);
    int iCanvasXBase = luaL_checkint(L, 4);
    int iCanvasYBase = luaL_checkint(L, 5);
    bool bShowHeat = lua_toboolean(L, 6) != 0;

    uint32_t iColourMyHosp = pCanvas->mapColour(0, 0, 70);
    uint32_t iColourWall = pCanvas->mapColour(255, 255, 255);
    uint32_t iColourDoor = pCanvas->mapColour(200, 200, 200);
    uint32_t iColourPurchasable = pCanvas->mapColour(255, 0, 0);

    const THMapNode *pNode = pMap->getNodeUnchecked(0, 0);
    const THMapNode *pOriginalNode = pMap->getOriginalNodeUnchecked(0, 0);
    int iCanvasY = iCanvasYBase + 3;
    int iMapWidth = pMap->getWidth();
    for(int iY = 0; iY < pMap->getHeight(); ++iY, iCanvasY += 3)
    {
        int iCanvasX = iCanvasXBase;
        for(int iX = 0; iX < iMapWidth; ++iX, ++pNode, ++pOriginalNode, iCanvasX += 3)
        {
            if(pOriginalNode->iFlags & THMN_Hospital)
            {
                uint32_t iColour = iColourMyHosp;
                if(!(pNode->iFlags & THMN_Hospital))
                {
                    // TODO: Replace 1 with player number
                    if(pMap->isParcelPurchasable(pNode->iParcelId, 1))
                        iColour = iColourPurchasable;
                    else
                        goto dont_paint_tile;
                }
                else if(bShowHeat)
                {
                    uint16_t iTemp = pMap->getNodeTemperature(pNode);
                    if(iTemp < 5200) // Less than 4 degrees
                        iTemp = 0;
                    else if(iTemp > 32767) // More than 25 degrees
                        iTemp = 255;
                    else // NB: 108 == (32767 - 5200) / 255
                        iTemp = (iTemp - 5200) / 108;

#define MIN_OK_TEMP 140
#define MAX_OK_TEMP 180
#define RangeScale(low, high, val, start, end) \
    Clamp8(start + (end - start) * (val - low) / (high - low))
                    switch(pMap->getTemperatureDisplay())
                    {
                    case THMT_MultiColour:
                    {
                        uint8_t iR = 0;
                        uint8_t iG = 0;
                        uint8_t iB = 70;
                        if(iTemp < MIN_OK_TEMP)
                            iB = RangeScale(0, MIN_OK_TEMP - 1, iTemp, 200, 60);
                        else if(iTemp < MAX_OK_TEMP)
                            iG = RangeScale(MIN_OK_TEMP, MAX_OK_TEMP - 1, iTemp, 140, 224);
                        else
                            iR = RangeScale(MAX_OK_TEMP, 255, iTemp, 224, 255);
                        iColour = pCanvas->mapColour(iR, iG, iB);
                        break;
                    }
                    case THMT_YellowRed:
                        if(iTemp < MIN_OK_TEMP) // Below 11 degrees
                        {
                            uint8_t iR = RangeScale(0, MIN_OK_TEMP - 1, iTemp, 100, 213);
                            uint8_t iG = RangeScale(0, MIN_OK_TEMP - 1, iTemp, 80, 180);
                            iColour = pCanvas->mapColour(iR, iG, 0);
                        }
                        else
                        {
                            uint8_t iR = RangeScale(MIN_OK_TEMP, 255, iTemp, 223, 235);
                            uint8_t iG = RangeScale(MIN_OK_TEMP, 255, iTemp, 184, 104);
                            uint8_t iB = RangeScale(MIN_OK_TEMP, 255, iTemp, 0, 53);
                            iColour = pCanvas->mapColour(iR, iG, iB);
                        }
                        break;
                    default:
                    case THMT_Red:
                        iColour = pCanvas->mapColour(static_cast<uint8_t>(iTemp), 0, 70);
                        break;
                    }
#undef RangeScale
                }
                pCanvas->fillRect(iColour, iCanvasX, iCanvasY, 3, 3);
            }
            dont_paint_tile:
#define IsWall(blk) ((82 <= ((blk) & 0xFF)) && (((blk) & 0xFF) <= 164))
#define IsWallDrawn(n) pMap->getNodeOwner(pNode) != 0 ? \
    IsWall(pNode->iBlock[n]) : IsWall(pOriginalNode->iBlock[n])
            if(IsWallDrawn(1)) {
                pCanvas->fillRect(iColourWall, iCanvasX, iCanvasY, 3, 1);

                // Draw entrance door
                if((pNode-1)->iFlags >> 24 == THOB_EntranceRightDoor) {
                    if (pNode->iFlags & THMN_Hospital) {
                        pCanvas->fillRect(iColourDoor, iCanvasX-6, iCanvasY-2, 9, 3);
                    } else {
                        pCanvas->fillRect(iColourDoor, iCanvasX-6, iCanvasY, 9, 3);
                    }
                }
            }
            if(IsWallDrawn(2)) {
                pCanvas->fillRect(iColourWall, iCanvasX, iCanvasY, 1, 3);

                // Draw entrance door
                if((pNode-iMapWidth)->iFlags >> 24 == THOB_EntranceRightDoor) {
                    if (pNode->iFlags & THMN_Hospital) {
                        pCanvas->fillRect(iColourDoor, iCanvasX-2, iCanvasY-6, 3, 9);
                    } else {
                        pCanvas->fillRect(iColourDoor, iCanvasX, iCanvasY-6, 3, 9);
                    }
                }
            }
#undef IsWallDrawn
#undef IsWall
        }