Alexander Shiryaev писал(а):
kekc_leader, так должно заработать:
Код:
PROCEDURE FillRect (surface: SDL.Surface; VAR rect: SDL.Rect; color: INTEGER): INTEGER;
CONST
SP = 4; (* register number of stack pointer *)
N = 12; (* 0 | 4 | 8 | 12 *)
VAR sp: INTEGER;
BEGIN
SYSTEM.GETREG(SP, sp);
SYSTEM.PUTREG(SP, sp DIV 16 * 16 - N);
RETURN SDL.FillRect(surface, rect, color)
END FillRect;
Константу N надо подобрать опытным путём (4 варианта)
Я как-то так пробовал, но вроде ошибся с тем, что думал, что SP растёт в другую сторону, поэтому попробую ещё раз! А пока «решил» проблему так:
Код:
PROCEDURE FillRect0(surface: SDL.Surface; VAR rect: SDL.Rect; color: INTEGER);
BEGIN
IF SDL.FillRect(surface, rect, color) = 0 THEN END
END FillRect0;
PROCEDURE FillRect1(surface: SDL.Surface; VAR rect: SDL.Rect; color: INTEGER);
VAR pad1: INTEGER;
BEGIN
IF SDL.FillRect(surface, rect, color) = 0 THEN END
END FillRect1;
PROCEDURE FillRect2(surface: SDL.Surface; VAR rect: SDL.Rect; color: INTEGER);
VAR pad1, pad2: INTEGER;
BEGIN
IF SDL.FillRect(surface, rect, color) = 0 THEN END
END FillRect2;
PROCEDURE FillRect3(surface: SDL.Surface; VAR rect: SDL.Rect; color: INTEGER);
VAR pad1, pad2, pad3: INTEGER;
BEGIN
IF SDL.FillRect(surface, rect, color) = 0 THEN END
END FillRect3;
PROCEDURE FillRect(surface: SDL.Surface; VAR rect: SDL.Rect; color: INTEGER);
CONST SP = 4; (* Register number of stack pointer *)
VAR sp: INTEGER;
BEGIN
CASE SYSTEM.ADR(sp) MOD 16 OF
0: FillRect0(surface, rect, color)
| 4: FillRect1(surface, rect, color)
| 8: FillRect2(surface, rect, color)
ELSE FillRect3(surface, rect, color) END
END FillRect;
PROCEDURE FillAll(surface: SDL.Surface; color: INTEGER);
VAR r: SDL.Rect;
BEGIN
(* Equivalent to SDL.FillRect(surface, NIL, color) *)
r.x := 0; r.y := 0; r.w := surface.w; r.h := surface.h;
FillRect(surface, r, color)
END FillAll;
PROCEDURE RenderClear0(renderer: SDL.Renderer);
BEGIN
IF SDL.RenderClear(renderer) = 0 THEN END
END RenderClear0;
PROCEDURE RenderClear1(renderer: SDL.Renderer);
VAR pad1: INTEGER;
BEGIN
IF SDL.RenderClear(renderer) = 0 THEN END
END RenderClear1;
PROCEDURE RenderClear2(renderer: SDL.Renderer);
VAR pad1, pad2: INTEGER;
BEGIN
IF SDL.RenderClear(renderer) = 0 THEN END
END RenderClear2;
PROCEDURE RenderClear3(renderer: SDL.Renderer);
VAR pad1, pad2, pad3: INTEGER;
BEGIN
IF SDL.RenderClear(renderer) = 0 THEN END
END RenderClear3;
PROCEDURE RenderClear(renderer: SDL.Renderer);
VAR sp: INTEGER;
BEGIN
CASE SYSTEM.ADR(sp) MOD 16 OF
0: RenderClear0(renderer)
| 4: RenderClear1(renderer)
| 8: RenderClear2(renderer)
ELSE RenderClear3(renderer) END
END RenderClear;
Сейчас работает и на Линуксовом Блэкбоксе, и на Виндоусовом. Пока тестировал, оказалось, что не SDL_FillRect может глючить (а может случайно и не заглючить) на Линуксе всегда, а SDL_RenderClear может глючить только в том случае, если при создании прорисовщика (SDL_Renderer) был выбран режим SDL_RENDERER_SOFTWARE. То есть если SDL_RENDERER_ACCELERATED, то очистка экрана идёт за счёт ГПУ, а если SOFTWARE, то за счёт того же SDL_FillRect:
Код:
/* Файл "src/render/software/SDL_render_sw.c" */
static int
SW_RenderClear(SDL_Renderer * renderer)
{
SDL_Surface *surface = SW_ActivateRenderer(renderer);
Uint32 color;
SDL_Rect clip_rect;
if (!surface) {
return -1;
}
color = SDL_MapRGBA(surface->format,
renderer->r, renderer->g, renderer->b, renderer->a);
/* By definition the clear ignores the clip rect */
clip_rect = surface->clip_rect;
SDL_SetClipRect(surface, NULL);
SDL_FillRect(surface, NULL, color);
SDL_SetClipRect(surface, &clip_rect);
return 0;
}