#include #include #include #include #include #include #include #include "ui.h" #define MAX_PATH_NUM 1024 const char *resources = "/home/stone/Project/netscore/"; // 绘制数字 static void drawBigNumber(SDL_Renderer* renderer, SDL_Texture* numberTexture, int x, int y) { static const int NumberWidth = 344, NumberHeight = 573; SDL_Rect dstRect = {x, y, NumberWidth, NumberHeight}; SDL_RenderCopy(renderer, numberTexture, NULL, &dstRect); } // 绘制数字 static void drawSmallNumber(SDL_Renderer* renderer, SDL_Texture* numberTexture, int x, int y) { static const int NumberWidth = 290, NumberHeight = 484; SDL_Rect dstRect = {x, y, NumberWidth, NumberHeight}; SDL_RenderCopy(renderer, numberTexture, NULL, &dstRect); } static void drawBox(SDL_Renderer* renderer, SDL_Texture* boxTexture, int x, int y) { static const int NumberWidth = 892, NumberHeight = 1044; SDL_Rect dstRect = {x, y, NumberWidth, NumberHeight}; SDL_RenderCopy(renderer, boxTexture, NULL, &dstRect); } static void drawWin(SDL_Renderer* renderer, SDL_Texture* winTexture, int x, int y) { static const int NumberWidth = 639, NumberHeight = 193; SDL_Rect dstRect = {x, y, NumberWidth, NumberHeight}; SDL_RenderCopy(renderer, winTexture, NULL, &dstRect); } static void drawNameTexture(struct Application *app, SDL_Texture *texture, int x, int y) { static const int NameWidth = 1120, NameHeight = 118; // 获取纹理的宽度和高度 int textureWidth, textureHeight; SDL_QueryTexture(texture, NULL, NULL, &textureWidth, &textureHeight); // 计算居中显示时的位置 int centerX = x + (NameWidth - textureWidth) / 2; int centerY = y + (NameHeight - textureHeight) / 2; // 创建目标矩形 SDL_Rect dstRect = { centerX, centerY, textureWidth, textureHeight }; SDL_RenderCopy(app->renderer, texture, NULL, &dstRect); } static SDL_Texture* loadTexture(struct Application *app, const char *path) { SDL_Surface* surface = IMG_Load(path); if (!surface) { return NULL; } SDL_Texture* texture = SDL_CreateTextureFromSurface(app->renderer, surface); SDL_FreeSurface(surface); return texture; } int initApplication(struct Application *app) { int i; app->ret = 0; app->errorString[0] = '\0'; app->initialized = 0; app->window = NULL; app->winWidth = 0; app->winHeight = 0; app->renderer = NULL; app->bgTexture = NULL; for (i = 0; i < 10; i++) app->bigNumTextures[i] = NULL; for (i = 0; i < 10; i++) app->smallNumTextures[i] = NULL; app->nameFont = NULL; app->p1NameTexture = app->p2NameTexture = NULL; for (i = 0; i < 2; i++) app->p1WinTexture[i] = app->p2WinTexture[i] = NULL; app->scoreHighLightTexture[0] = app->scoreHighLightTexture[1] = NULL; app->p1Name[0] = '\0'; app->p2Name[0] = '\0'; app->roundNum = app->roundNumSt = app->roundNumNd = 0; app->p1Num = app->p1NumSt = app->p1NumNd = 0; app->p2Num = app->p2NumSt = app->p2NumNd = 0; app->p1Win = app->p2Win = 0; app->isKey = 0; app->updateRequire = 1; app->mutex = NULL; if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: SDL_Init: %s", SDL_GetError()); return -1; } app->initialized = 1; if (TTF_Init() == -1) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: TTF_Init: %s", TTF_GetError()); return -1; } app->window = SDL_CreateWindow("计分板", 0, 0, 3840, 1100, SDL_WINDOW_FULLSCREEN); if (!app->window) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: SDL_CreateWindow: %s", SDL_GetError()); return -1; } SDL_GetWindowSize(app->window, &app->winWidth, &app->winHeight); app->renderer = SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED); if (!app->renderer) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: SDL_CreateRenderer: %s", SDL_GetError()); return -1; } // 加载背景图片 { char path[MAX_PATH_NUM]; snprintf(path, MAX_PATH_NUM, "%s%s%s", resources, "img/", "bg.png"); SDL_Surface* surface = IMG_Load(path); if (!surface) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load bg image %s: %s", path, IMG_GetError()); return -1; } app->bgTexture = SDL_CreateTextureFromSurface(app->renderer, surface); SDL_FreeSurface(surface); } for (i = 0; i < 10; i++) { char path[MAX_PATH_NUM]; snprintf(path, MAX_PATH_NUM, "%s%s/%d.png", resources, "img/big", i); app->bigNumTextures[i] = loadTexture(app, path); if (!app->bigNumTextures[i]) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load big numer image %s: %s", path, IMG_GetError()); return -1; } } for (i = 0; i < 10; i++) { char path[MAX_PATH_NUM]; snprintf(path, MAX_PATH_NUM, "%s%s/%d.png", resources, "img/small", i); app->smallNumTextures[i] = loadTexture(app, path); if (!app->smallNumTextures[i]) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load small numer image %s: %s", path, IMG_GetError()); return -1; } } { char path[MAX_PATH_NUM]; snprintf(path, sizeof(path), "%s%s%s", resources, "font/", "msyh.ttc"); app->nameFont = TTF_OpenFont(path, 120); if (app->nameFont == NULL) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load font path %s: %s", path, TTF_GetError()); return -1; } } for (i = 0; i < 2; ++i) { char path[MAX_PATH_NUM]; snprintf(path, sizeof(path), "%s%s%s_%d.png", resources, "img/", "box", i); app->scoreHighLightTexture[i] = loadTexture(app, path); if (!app->scoreHighLightTexture[i]) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load box image %s: %s", path, IMG_GetError()); return -1; } } for (i = 0; i < 2; ++i) { char path[MAX_PATH_NUM]; snprintf(path, sizeof(path), "%s%s%s_%d.png", resources, "img/", "p1_win", i); app->p1WinTexture[i] = loadTexture(app, path); if (!app->p1WinTexture[i]) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load p1_win image %s: %s", path, IMG_GetError()); return -1; } snprintf(path, sizeof(path), "%s%s%s_%d.png", resources, "img/", "p2_win", i); app->p2WinTexture[i] = loadTexture(app, path); if (!app->p2WinTexture[i]) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: Load p2_win image %s: %s", path, IMG_GetError()); return -1; } } app->mutex = SDL_CreateMutex(); if (app->mutex == NULL) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: create mutex error: %s", SDL_GetError()); return -1; } return 0; } void drawApplication(struct Application *app) { // 清空渲染器 SDL_RenderClear(app->renderer); SDL_Color textColor = { 255, 255, 255 }; // 白色 SDL_Surface* surface = NULL; { SDL_Surface* surface = NULL; if (strnlen(app->p1Name, sizeof(app->p1Name)) != 0) { surface = TTF_RenderUTF8_Solid(app->nameFont, app->p1Name, textColor); if (!surface) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: create utf-8 surface error %s: %s", app->p1Name, TTF_GetError()); } } if (app->p1NameTexture) SDL_DestroyTexture(app->p1NameTexture); app->p1NameTexture = NULL; if (surface) { app->p1NameTexture = SDL_CreateTextureFromSurface(app->renderer, surface); if (!app->p1NameTexture) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: create texture error %s", SDL_GetError()); } SDL_FreeSurface(surface); } } { if (strnlen(app->p2Name, sizeof(app->p2Name)) != 0) { surface = TTF_RenderUTF8_Solid(app->nameFont, app->p2Name, textColor); if (!surface) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: create utf-8 surface error %s: %s", app->p2Name, TTF_GetError()); } } if (app->p2NameTexture) SDL_DestroyTexture(app->p2NameTexture); app->p2NameTexture = NULL; if (surface) { app->p2NameTexture = SDL_CreateTextureFromSurface(app->renderer, surface); if (!app->p2NameTexture) { snprintf(app->errorString, sizeof(app->errorString), "[ERROR]: create texture error %s", SDL_GetError()); } SDL_FreeSurface(surface); } } // 绘制背景图片 SDL_RenderCopy(app->renderer, app->bgTexture, NULL, NULL); drawBox(app->renderer, app->scoreHighLightTexture[app->isKey], 1475, 29); if (app->p1NameTexture) drawNameTexture(app, app->p1NameTexture, 233, 136); if (app->p2NameTexture) drawNameTexture(app, app->p2NameTexture, 2490, 136); drawSmallNumber(app->renderer, app->smallNumTextures[app->roundNumSt], 1589, 409); drawSmallNumber(app->renderer, app->smallNumTextures[app->roundNumNd], 1962, 409); drawBigNumber(app->renderer, app->bigNumTextures[app->p1NumSt], 455, 317); drawBigNumber(app->renderer, app->bigNumTextures[app->p1NumNd], 896, 317); drawBigNumber(app->renderer, app->bigNumTextures[app->p2NumSt], 2600, 317); drawBigNumber(app->renderer, app->bigNumTextures[app->p2NumNd], 3041, 317); drawWin(app->renderer, app->p1WinTexture[app->p1Win], 528, 883); drawWin(app->renderer, app->p2WinTexture[app->p2Win], 2673, 883); SDL_RenderPresent(app->renderer); } void termApplication(struct Application *app) { if (app->initialized == 0) return; int i; if (app->mutex) SDL_DestroyMutex(app->mutex); for (i = 0; i < 2; i++) if (app->scoreHighLightTexture[i]) SDL_DestroyTexture(app->scoreHighLightTexture[i]); for (i = 0; i < 2; i++) { if (app->p1WinTexture[i]) SDL_DestroyTexture(app->p1WinTexture[i]); if (app->p2WinTexture[i]) SDL_DestroyTexture(app->p2WinTexture[i]); } if (app->p1NameTexture) SDL_DestroyTexture(app->p1NameTexture); if (app->p2NameTexture) SDL_DestroyTexture(app->p2NameTexture); if (app->nameFont) TTF_CloseFont(app->nameFont); for (i = 0; i < 10; i++) if (app->smallNumTextures[i]) SDL_DestroyTexture(app->smallNumTextures[i]); for (i = 0; i < 10; i++) if (app->bigNumTextures[i]) SDL_DestroyTexture(app->bigNumTextures[i]); if (app->bgTexture) SDL_DestroyTexture(app->bgTexture); if (app->renderer) SDL_DestroyRenderer(app->renderer); if (app->window) SDL_DestroyWindow(app->window); if (TTF_WasInit()) TTF_Quit(); SDL_Quit(); app->initialized = 0; } int updateApplicationMode(struct Application *app, uint8 isKey) { app->isKey = isKey; return 0; } int updateApplication(struct Application *app, const char *p1Name, const char *p2Name, int roundNum, int p1Score, int p2Score) { printf("%s, %s, %d, %d, %d\n", p1Name, p2Name, roundNum, p1Score, p2Score); SDL_LockMutex(app->mutex); if ((strcmp(p1Name, app->p1Name) == 0 && strcmp(p2Name, app->p2Name) == 0) || (strcmp(p1Name, app->p2Name) == 0 && strcmp(p2Name, app->p1Name))) { if (p1Score - app->p1Num == 1 && p2Score == app->p2Num) { app->p1Win = 1; } else { app->p1Win = 0; } if (p1Score == app->p1Num && p2Score - app->p2Num == 1) { app->p2Win = 1; } else { app->p2Win = 0; } } if (p1Name != app->p1Name && strcmp(p1Name, app->p1Name) != 0 && strlen(p1Name) <= 30) { memset(app->p1Name, 0, sizeof(app->p1Name)); strncpy(app->p1Name, p1Name, sizeof(app->p1Name) - 1); } if (p2Name != app->p2Name && strcmp(p2Name, app->p2Name) != 0 && strlen(p2Name) <= 30) { memset(app->p2Name, 0, sizeof(app->p2Name)); strncpy(app->p2Name, p2Name, sizeof(app->p2Name) - 1); } app->roundNum = roundNum % 100; app->roundNumSt = (app->roundNum / 10) % 10; app->roundNumNd = app->roundNum % 10; app->p1Num = p1Score % 100; app->p1NumSt = (app->p1Num / 10) % 10; app->p1NumNd = app->p1Num % 10; app->p2Num = p2Score % 100; app->p2NumSt = (app->p2Num / 10) % 10; app->p2NumNd = app->p2Num % 10; SDL_UnlockMutex(app->mutex); app->updateRequire = 1; return 0; } /* int main() { struct Application myApp, *app = &myApp; if (initApplication(app)) { printf("初始化应用失败: %s\n", app->errorString); termApplication(app); return 0; } if (app->initialized) { updateApplication(app, "昵称最多有八个字", "昵称最多有八个字", 5, 6, 6); runApplication(app); } termApplication(app); return 0; }*/