From 5855d34a6e987cbbd853a2013d9ee3a006b1f6a6 Mon Sep 17 00:00:00 2001 From: Bill Kendrick Date: Sat, 30 Dec 2023 13:44:00 -0800 Subject: [PATCH] N-pt perspective supports beginner complexity level The three "select" (vanishing point editors) are not available, and a second 3-point perspective drawing tool, with an alternative (downward-looking) set of vanishing points, is made available. --- docs/CHANGES.txt | 6 +- magic/icons/3pt_persp_draw_alt.png | Bin 0 -> 1501 bytes magic/src/n_pt_persp.c | 386 ++++++++++++++++++++++++----- 3 files changed, 321 insertions(+), 71 deletions(-) create mode 100644 magic/icons/3pt_persp_draw_alt.png diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index d8411a729..8308fbe12 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -6,7 +6,7 @@ Copyright (c) 2002-2023 Various contributors (see below, and AUTHORS.txt) https://tuxpaint.org/ -2023.December.29 (0.9.32) +2023.December.30 (0.9.32) * Improvements to Magic tools: ---------------------------- * Support for complexity levels in Magic tools via the plugin API. @@ -38,9 +38,9 @@ https://tuxpaint.org/ point towards them, or along the horizon defined by the first two. + None of these tools are available when in "novice" complexity mode (see above). - + WIP - "Select" tools (to edit vanishing points) are not offered + + "Select" tools (to edit vanishing points) are not offered when in "beginner" complexity mode. - - WIP - Also, two "3-Point Draw" tools are provided in "beginner" + - Also, two "3-Point Draw" tools are provided in "beginner" mode, to offer both 'looking up' and 'looking down' perspectives. + Code: Bill Kendrick + Sounds: diff --git a/magic/icons/3pt_persp_draw_alt.png b/magic/icons/3pt_persp_draw_alt.png new file mode 100644 index 0000000000000000000000000000000000000000..20a75f9c7c6c1b6fd0dc61499d8b3bbde9db255b GIT binary patch literal 1501 zcmeAS@N?(olHy`uVBq!ia0vp^20$#w!3-p0t8zaxFfe5W_=LCuxoCiqkr7#hnHi*o z7{J8DM2s>_H9#AIfQ5wxQwnH1PzopxA>j&$u?tNLTrYVHtfmp;47hc06M(unIXNNX z?Ck7t1$Y>6y*xZTc$A?@!F3^vv$3%ubFr#HRsd(Sva$l%qN1X_yu5Hh;u&JDp7uc1 zXG?w?AiGc0B^KWM%9{lnzp=CiNAu}S|sH{o;Ur>wj?x7G9KUE6!V zhFg?5%rfm`f*Y&YMS*wG%MCeJO>^n}`o2q}$>60(`t_UJdJep*wojS0!Xsk-o?VZ! z4ajmbt5pNyuL_knOxz#-g=z65l^gtiJN0aXJL_woCfc|kXFAEq=-+r{ zdTHeI2fr?PwJunwubmutDFv9FLOop^Ln`8?o_}2YxK_mB%XPjHJp|`(X>Ers3J-U6jc3BCZ+VtG>(C*cW3s_t~@A+PIT`BY1B<|-= zmdwr)Tr`a-)HkBX;=)I<#Hm*mcHO?h_c>XROVrJSQ{76W-A7;b(6OURr<|8I%unNW z`ct@I*`~iNe74I4#IB}y`kAIN@o1MZY`AAGbZlLwsl}U}ikmbaO?z>$?J$R=;&)f` z7Ynq_Jm0n7P1)qJf6Jqr(-_}Gg>o|dd-e87&l8pt8$RD;o$%l$TR^}*@%H@h{+)6X zEvhHArzv-ubRLlxy*;h;)4{`&6B(xda`D@}^qhOqG7g16eda0YvwzIc$>n(9WFuaC zXY)jt?%>8ehM&(=>uUnYv z*4~}Sm>*RXP#4-&EO$@t!1a4xKh(IyeCpb{S1B&=WxjvB_tWA2+8v*Q4L*EUs57km z^T@c-`>!^`W?kR4i_Dj>Utbm4usk<$LfMb&B`nwD-T!TSP~Q5kpX=F?Nlxi@-9i8U xbnl$G^6`6veGVV&UH+UF|DmtD - December 12, 2023 - December 29, 2023 + December 12, 2023 - December 30, 2023 */ @@ -19,30 +26,76 @@ #define SNAP 10 - +/* All _possible_ tools */ enum { - TOOL_1PT_SELECT, - TOOL_1PT_DRAW, - TOOL_2PT_SELECT, - TOOL_2PT_DRAW, - TOOL_3PT_SELECT, - TOOL_3PT_DRAW, + TOOL_1PT_SELECT, /* advanced & beginner */ + TOOL_1PT_DRAW, /* advanced only */ + TOOL_2PT_SELECT, /* advanced & beginner */ + TOOL_2PT_DRAW, /* advanced only */ + TOOL_3PT_SELECT, /* advanced & beginner */ + TOOL_3PT_DRAW, /* advanced only */ + TOOL_3PT_SELECT_ALT, /* beginner only (not directly accessible; used for drawing guideS) */ + TOOL_3PT_DRAW_ALT, /* beginner only */ NUM_TOOLS }; +// #define DEBUG -enum { - SND_SELECT, - SND_DRAW_CLICK, - SND_DRAW_RELEASE, - NUM_SNDS +#ifdef DEBUG +char * tool_debug_names[NUM_TOOLS] = { + "1pt select", + "1pt draw", + "2pt select", + "2pt draw", + "3pt select", + "3pt draw", + "3pt select alt", + "3pt draw alt", +}; +#endif + +Uint8 complexity; + +int num_tools[NUM_MAGIC_COMPLEXITY_LEVELS] = { + 0, /* Novice */ + 4, /* Beginner */ + 6, /* Advanced */ }; -const char *sound_filenames[NUM_SNDS] = { - "n_pt_persp_select.ogg", - "n_pt_persp_click.ogg", - "n_pt_persp_release.ogg", +int * which_to_tool; + +int which_to_tool_per_complexity[NUM_MAGIC_COMPLEXITY_LEVELS][NUM_TOOLS] = { + /* Novice */ + { + -1, + -1, + -1, + -1, + -1, + -1, + -1, + }, + /* Beginner */ + { + TOOL_1PT_DRAW, + TOOL_2PT_DRAW, + TOOL_3PT_DRAW, + TOOL_3PT_DRAW_ALT, + -1, + -1, + -1, + }, + /* Advanced */ + { + TOOL_1PT_SELECT, + TOOL_1PT_DRAW, + TOOL_2PT_SELECT, + TOOL_2PT_DRAW, + TOOL_3PT_SELECT, + TOOL_3PT_DRAW, + -1, + }, }; const char *icon_filenames[NUM_TOOLS] = { @@ -52,6 +105,8 @@ const char *icon_filenames[NUM_TOOLS] = { "2pt_persp_draw.png", "3pt_persp_select.png", "3pt_persp_draw.png", + "", + "3pt_persp_draw_alt.png", }; @@ -62,6 +117,8 @@ const char *tool_names[NUM_TOOLS] = { gettext_noop("2-Point Draw"), gettext_noop("3-Point Select"), gettext_noop("3-Point Draw"), + "", + gettext_noop("3-Point Draw Down"), }; @@ -72,10 +129,26 @@ const char *tool_descriptions[NUM_TOOLS] = { gettext_noop("Click and drag to draw lines with your 2-point perspective vanishing points."), gettext_noop("Click three places in your drawing to pick vanishing points for the 3-point perspective painting tool."), gettext_noop("Click and drag to draw lines with your 3-point perspective vanishing points."), + "", + gettext_noop("Click and drag to draw lines with your 3-point perspective vanishing points (downward perspective)."), }; -Mix_Chunk *sound_effects[NUM_TOOLS]; +/* Sound effects (same for everyone) */ +enum { + SND_SELECT, + SND_DRAW_CLICK, + SND_DRAW_RELEASE, + NUM_SNDS +}; + +Mix_Chunk *sound_effects[NUM_SNDS]; + +const char *sound_filenames[NUM_SNDS] = { + "n_pt_persp_select.ogg", + "n_pt_persp_click.ogg", + "n_pt_persp_release.ogg", +}; Uint8 n_pt_persp_r, n_pt_persp_g, n_pt_persp_b; Uint8 n_pt_persp_size = 1; @@ -84,6 +157,7 @@ SDL_Surface * n_pt_persp_snapshot = NULL; int a1_pt_x, a1_pt_y; int a2_pt_x[2], a2_pt_y[2], a2_pt_cur; int a3_pt_x[3], a3_pt_y[3], a3_pt_cur; +int a3b_pt_x[3], a3b_pt_y[3]; int line_start_x, line_start_y; float a2_valid_angle[8]; float a3_valid_angle[8]; @@ -109,7 +183,7 @@ void n_pt_persp_drag(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot, int old_x, int old_y, int x, int y, SDL_Rect * update_rect); -void n_pt_persp_work(magic_api * api, int which, +void n_pt_persp_work(magic_api * api, int tool, SDL_Surface * canvas, int x, int y, SDL_Rect * update_rect, int xor); void n_pt_persp_release(magic_api * api, int which, @@ -121,15 +195,15 @@ void n_pt_persp_set_color(magic_api * api, int which, SDL_Surface * canvas, void n_pt_persp_set_size(magic_api * api, int which, int mode, SDL_Surface * canvas, SDL_Surface * last, Uint8 size, SDL_Rect * update_rect); -void n_pt_persp_line_xor_callback(void *pointer, int which, SDL_Surface * canvas, +void n_pt_persp_line_xor_callback(void *pointer, int tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y); -void n_pt_persp_line_callback(void *pointer, int which, SDL_Surface * canvas, +void n_pt_persp_line_callback(void *pointer, int tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y); void n_pt_persp_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas); void n_pt_persp_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas); -void n_pt_persp_draw_points(magic_api * api, int which, SDL_Surface * canvas); +void n_pt_persp_draw_points(magic_api * api, int tool, SDL_Surface * canvas); void n_pt_persp_draw_one_point(magic_api * api, SDL_Surface * canvas, int x, int y, int i); @@ -144,8 +218,34 @@ int n_pt_persp_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, U int i; char filename[1024]; + for (i = 0; i < NUM_SNDS; i++) { + sound_effects[i] = NULL; + } + + complexity = complexity_level; + which_to_tool = which_to_tool_per_complexity[complexity_level]; + +#ifdef DEBUG + printf("complexity level %d; tool mapping:\n", complexity); + fflush(stdout); + for (i = 0; i < NUM_TOOLS; i++) { + printf("%d -> %d ", i, which_to_tool[i]); + fflush(stdout); + if (which_to_tool[i] != -1) { + printf("%s", tool_debug_names[which_to_tool[i]]); + } + printf("\n"); + fflush(stdout); + } +#endif + + if (complexity_level == MAGIC_COMPLEXITY_NOVICE) { /* No N-point perspective tools _at all_, if in Novice mode */ +#ifdef DEBUG + printf("n_pt_persp_init -- MAGIC_COMPLEXITY_NOVICE so no tools for you!\n"); + fflush(stdout); +#endif return 0; } @@ -186,6 +286,17 @@ int n_pt_persp_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, U a3_pt_cur = 0; + /* 3-pt perspective alternative initial vanishing points: bottom center, and left and right near top of canvas */ + a3b_pt_x[0] = api->canvas_w * 1 / 20; + a3b_pt_y[0] = api->canvas_h * 1 / 20; + + a3b_pt_x[1] = api->canvas_w * 19 / 20; + a3b_pt_y[1] = api->canvas_h * 1 / 20; + + a3b_pt_x[2] = api->canvas_w / 2; + a3b_pt_y[2] = api->canvas_h * 19 / 20; + + n_pt_persp_snapshot = SDL_CreateRGBSurface(SDL_SWSURFACE, api->canvas_w, api->canvas_h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); // FIXME: Safe? if (n_pt_persp_snapshot == NULL) { @@ -199,7 +310,7 @@ int n_pt_persp_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, U int n_pt_persp_get_tool_count(magic_api * api ATTRIBUTE_UNUSED) { - return (NUM_TOOLS); + return (num_tools[complexity]); } @@ -207,8 +318,14 @@ SDL_Surface *n_pt_persp_get_icon(magic_api * api, int which) { char filename[1024]; +#ifdef DEBUG + printf("\nn_pt_persp_get_icon\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + snprintf(filename, sizeof(filename), "%s/images/magic/%s", - api->data_directory, icon_filenames[which]); + api->data_directory, icon_filenames[which_to_tool[which]]); return (IMG_Load(filename)); } @@ -216,7 +333,12 @@ SDL_Surface *n_pt_persp_get_icon(magic_api * api, int which) char *n_pt_persp_get_name(magic_api * api ATTRIBUTE_UNUSED, int which) { - return (strdup(gettext(tool_names[which]))); +#ifdef DEBUG + printf("\nn_pt_persp_get_name\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + return (strdup(gettext(tool_names[which_to_tool[which]]))); } @@ -228,13 +350,26 @@ int n_pt_persp_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U char *n_pt_persp_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) { - return (strdup(gettext(tool_descriptions[which]))); +#ifdef DEBUG + printf("\nn_pt_persp_get_description\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + return (strdup(gettext(tool_descriptions[which_to_tool[which]]))); } int n_pt_persp_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which) { - if (which == TOOL_1PT_DRAW || which == TOOL_2PT_DRAW || which == TOOL_3PT_DRAW) +#ifdef DEBUG + printf("\nn_pt_persp_requires_colors\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + + if (which == TOOL_1PT_DRAW || which == TOOL_2PT_DRAW || which == TOOL_3PT_DRAW || which == TOOL_3PT_DRAW_ALT) return 1; else return 0; @@ -248,7 +383,15 @@ int n_pt_persp_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSE Uint8 n_pt_persp_accepted_sizes(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED) { - if (which == TOOL_1PT_DRAW || which == TOOL_2PT_DRAW || which == TOOL_3PT_DRAW) +#ifdef DEBUG + printf("\nn_pt_persp_accepted_sizes\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + + if (which == TOOL_1PT_DRAW || which == TOOL_2PT_DRAW || which == TOOL_3PT_DRAW || which == TOOL_3PT_DRAW_ALT) return 4; else return 0; @@ -285,6 +428,14 @@ void n_pt_persp_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, int pick, i; float dist, min_dist; +#ifdef DEBUG + printf("\nn_pt_persp_click\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + pick = 0; min_dist = FLT_MAX; @@ -372,6 +523,24 @@ void n_pt_persp_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, a3_valid_angle[6] = atan2(a3_pt_y[2] - y, a3_pt_x[2] - x); a3_valid_angle[7] = a3_valid_angle[6] + M_PI; + for (i = 0; i < 8; i++) { + if (a3_valid_angle[i] > M_PI) { + a3_valid_angle[i] -= (M_PI * 2); + } + } + } else if (which == TOOL_3PT_DRAW_ALT) { + /* Horizon between vanishing points, and perpendicular (rise above/below) */ + a3_valid_angle[0] = atan2(a3b_pt_y[1] - a3b_pt_y[0], a3b_pt_x[1] - a3b_pt_x[0]); + a3_valid_angle[1] = a3_valid_angle[0] + M_PI; + + /* Angles that point toward the three vanishing points */ + a3_valid_angle[2] = atan2(a3b_pt_y[0] - y, a3b_pt_x[0] - x); + a3_valid_angle[3] = a3_valid_angle[2] + M_PI; + a3_valid_angle[4] = atan2(a3b_pt_y[1] - y, a3b_pt_x[1] - x); + a3_valid_angle[5] = a3_valid_angle[4] + M_PI; + a3_valid_angle[6] = atan2(a3b_pt_y[2] - y, a3b_pt_x[2] - x); + a3_valid_angle[7] = a3_valid_angle[6] + M_PI; + for (i = 0; i < 8; i++) { if (a3_valid_angle[i] > M_PI) { a3_valid_angle[i] -= (M_PI * 2); @@ -408,8 +577,16 @@ void n_pt_persp_drag(magic_api * api, int which, int i, x1, y1, x2, y2; float slope; +#ifdef DEBUG + printf("\nn_pt_persp_drag\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + /* Draw the line (preview) */ - n_pt_persp_work(api, which, canvas, x, y, update_rect, 1); + n_pt_persp_work(api, which /* the tool */, canvas, x, y, update_rect, 1); /* Show some guides */ if (which == TOOL_1PT_DRAW) { @@ -485,13 +662,31 @@ void n_pt_persp_drag(magic_api * api, int which, n_pt_persp_line_xor_callback); } } - } else if (which == TOOL_3PT_DRAW) { + } else if (which == TOOL_3PT_DRAW || which == TOOL_3PT_DRAW_ALT) { /* 3-point perspective - draw */ - n_pt_persp_draw_points(api, TOOL_3PT_SELECT, canvas); + int a3_x[3], a3_y[3]; + + if (which == TOOL_3PT_DRAW) { + a3_x[0] = a3_pt_x[0]; + a3_y[0] = a3_pt_y[0]; + a3_x[1] = a3_pt_x[1]; + a3_y[1] = a3_pt_y[1]; + a3_x[2] = a3_pt_x[2]; + a3_y[2] = a3_pt_y[2]; + n_pt_persp_draw_points(api, TOOL_3PT_SELECT, canvas); + } else { + a3_x[0] = a3b_pt_x[0]; + a3_y[0] = a3b_pt_y[0]; + a3_x[1] = a3b_pt_x[1]; + a3_y[1] = a3b_pt_y[1]; + a3_x[2] = a3b_pt_x[2]; + a3_y[2] = a3b_pt_y[2]; + n_pt_persp_draw_points(api, TOOL_3PT_SELECT_ALT, canvas); + } /* Horizon line (from the cursor) */ - slope = ((float) a3_pt_y[0] - (float) a3_pt_y[1]) / ((float) a3_pt_x[0] - (float) a3_pt_x[1]); + slope = ((float) a3_y[0] - (float) a3_y[1]) / ((float) a3_x[0] - (float) a3_x[1]); x1 = 0; y1 = y - (x * slope); x2 = canvas->w; @@ -504,13 +699,13 @@ void n_pt_persp_drag(magic_api * api, int which, /* Diagonal lines from cursor to the vanishing points */ for (i = 0; i < 3; i++) { - if (x != a3_pt_x[i]) { - slope = ((float) y - (float) a3_pt_y[i]) / ((float) x - (float) a3_pt_x[i]); + if (x != a3_x[i]) { + slope = ((float) y - (float) a3_y[i]) / ((float) x - (float) a3_x[i]); x1 = 0; - y1 = a3_pt_y[i] - (a3_pt_x[i] * slope); + y1 = a3_y[i] - (a3_x[i] * slope); x2 = canvas->w; - y2 = a3_pt_y[i] + ((canvas->w - a3_pt_x[i]) * slope); + y2 = a3_y[i] + ((canvas->w - a3_x[i]) * slope); api->line((void *) api, which, canvas, NULL, x1, y1, x2, y2, 2, @@ -538,7 +733,7 @@ void n_pt_persp_drag(magic_api * api, int which, } } -void n_pt_persp_work(magic_api * api, int which, +void n_pt_persp_work(magic_api * api, int tool, SDL_Surface * canvas, int x, int y, SDL_Rect * update_rect, int xor) { @@ -551,11 +746,19 @@ void n_pt_persp_work(magic_api * api, int which, if (n_pt_persp_snapshot == NULL) return; + /* N.B. "which" is already set to the appropriate tool by the calling function! */ + +#ifdef DEBUG + printf("\nn_pt_persp_work\n"); + printf("%d (%s)\n", tool, tool_debug_names[tool]); + fflush(stdout); +#endif + /* Adhere x & y to perspective! */ x1 = y1 = x2 = y2 = 0; - if (which == TOOL_1PT_DRAW) { + if (tool == TOOL_1PT_DRAW) { /* 1-point perspective */ x1 = line_start_x; @@ -593,14 +796,14 @@ void n_pt_persp_work(magic_api * api, int which, y2 = y1; } } - } else if (which == TOOL_2PT_DRAW || which == TOOL_3PT_DRAW) { + } else if (tool == TOOL_2PT_DRAW || tool == TOOL_3PT_DRAW || tool == TOOL_3PT_DRAW_ALT) { float * valid_angle; /* 2- & 3-point perspective */ - if (which == TOOL_2PT_DRAW) { + if (tool == TOOL_2PT_DRAW) { valid_angle = a2_valid_angle; - } else { + } else { /* TOOL_3PT_DRAW || TOOL_3PT_DRAW_ALT */ valid_angle = a3_valid_angle; } @@ -656,13 +859,13 @@ void n_pt_persp_work(magic_api * api, int which, if (xor) { /* Still moving; use XOR */ - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 3, n_pt_persp_line_xor_callback); } else { /* Released; draw the line for real */ - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 1, n_pt_persp_line_callback); } @@ -678,6 +881,14 @@ void n_pt_persp_release(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y, SDL_Rect * update_rect) { +#ifdef DEBUG + printf("\nn_pt_persp_release\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + if (which == TOOL_1PT_SELECT) { /* 1-point perspective - vanishing point drag released */ api->stopsound(); @@ -725,7 +936,7 @@ void n_pt_persp_set_size(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_U } -void n_pt_persp_line_xor_callback(void *pointer, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas, +void n_pt_persp_line_xor_callback(void *pointer, int tool ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) { magic_api *api = (magic_api *) pointer; @@ -734,7 +945,7 @@ void n_pt_persp_line_xor_callback(void *pointer, int which ATTRIBUTE_UNUSED, SDL api->xorpixel(canvas, x + 1, y + 1); } -void n_pt_persp_line_callback(void *pointer ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, +void n_pt_persp_line_callback(void *pointer ATTRIBUTE_UNUSED, int tool ATTRIBUTE_UNUSED, SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y) { @@ -751,6 +962,14 @@ void n_pt_persp_line_callback(void *pointer ATTRIBUTE_UNUSED, int which ATTRIBUT void n_pt_persp_switchin(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) { +#ifdef DEBUG + printf("\nn_pt_persp_switchin\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + if (which == TOOL_1PT_SELECT || which == TOOL_2PT_SELECT || which == TOOL_3PT_SELECT) { SDL_BlitSurface(canvas, NULL, n_pt_persp_snapshot, NULL); @@ -761,16 +980,30 @@ void n_pt_persp_switchin(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, void n_pt_persp_switchout(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED, SDL_Surface * canvas) { +#ifdef DEBUG + printf("\nn_pt_persp_switchout\n"); + printf("%d becomes %d (%s)\n", which, which_to_tool[which], tool_debug_names[which_to_tool[which]]); + fflush(stdout); +#endif + + which = which_to_tool[which]; + if (which == TOOL_1PT_SELECT || which == TOOL_2PT_SELECT || which == TOOL_3PT_SELECT) { SDL_BlitSurface(n_pt_persp_snapshot, NULL, canvas, NULL); } } -void n_pt_persp_draw_points(magic_api * api, int which, SDL_Surface * canvas) { +void n_pt_persp_draw_points(magic_api * api, int tool, SDL_Surface * canvas) { int i, l, m, x1, y1, x2, y2, x; float slope; - if (which == TOOL_1PT_SELECT) { +#ifdef DEBUG + printf("\nn_pt_persp_draw_points\n"); + printf("%d (%s)\n", tool, tool_debug_names[tool]); + fflush(stdout); +#endif + + if (tool == TOOL_1PT_SELECT) { /* 1-point perspective */ n_pt_persp_draw_one_point(api, canvas, a1_pt_x, a1_pt_y, 0); @@ -791,7 +1024,7 @@ void n_pt_persp_draw_points(magic_api * api, int which, SDL_Surface * canvas) { slope = ((float) a1_pt_y - (float) y1) / ((float) a1_pt_x - (float) x1); y2 = y1 + (x2 - x1) * slope; - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 6, n_pt_persp_line_xor_callback); @@ -805,13 +1038,13 @@ void n_pt_persp_draw_points(magic_api * api, int which, SDL_Surface * canvas) { yy1 = a1_pt_y + (a1_pt_x - xx) * slope; yy2 = a1_pt_y + (xx - a1_pt_x) * slope; - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, xx, yy1, xx, yy2, 3, n_pt_persp_line_xor_callback); } } } - } else if (which == TOOL_2PT_SELECT) { + } else if (tool == TOOL_2PT_SELECT) { /* 2-point perspective */ for (i = 0; i < 2; i++) { @@ -825,7 +1058,7 @@ void n_pt_persp_draw_points(magic_api * api, int which, SDL_Surface * canvas) { x2 = canvas->w; y2 = a2_pt_y[0] + ((canvas->w - a2_pt_x[0]) * slope); - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 12, n_pt_persp_line_xor_callback); @@ -850,50 +1083,67 @@ void n_pt_persp_draw_points(magic_api * api, int which, SDL_Surface * canvas) { y2 = canvas->h; } - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 12, n_pt_persp_line_xor_callback); - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, a2_pt_x[0], a2_pt_y[0], x2, y2, 12, n_pt_persp_line_xor_callback); - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, a2_pt_x[1], a2_pt_y[1], x2, y2, 12, n_pt_persp_line_xor_callback); - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, a2_pt_x[0], a2_pt_y[0], 12, n_pt_persp_line_xor_callback); - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, a2_pt_x[1], a2_pt_y[1], 12, n_pt_persp_line_xor_callback); - } else if (which == TOOL_3PT_SELECT) { + } else if (tool == TOOL_3PT_SELECT || tool == TOOL_3PT_SELECT_ALT) { /* 3-point perspective */ + int a3_x[3], a3_y[3]; + + if (tool == TOOL_3PT_SELECT) { + a3_x[0] = a3_pt_x[0]; + a3_y[0] = a3_pt_y[0]; + a3_x[1] = a3_pt_x[1]; + a3_y[1] = a3_pt_y[1]; + a3_x[2] = a3_pt_x[2]; + a3_y[2] = a3_pt_y[2]; + } else { + a3_x[0] = a3b_pt_x[0]; + a3_y[0] = a3b_pt_y[0]; + a3_x[1] = a3b_pt_x[1]; + a3_y[1] = a3b_pt_y[1]; + a3_x[2] = a3b_pt_x[2]; + a3_y[2] = a3b_pt_y[2]; + } for (i = 0; i < 3; i++) { - n_pt_persp_draw_one_point(api, canvas, a3_pt_x[i], a3_pt_y[i], i); + n_pt_persp_draw_one_point(api, canvas, a3_x[i], a3_y[i], i); } /* Horizon line (vanishing point) */ - slope = ((float) a3_pt_y[0] - (float) a3_pt_y[1]) / ((float) a3_pt_x[0] - (float) a3_pt_x[1]); + slope = ((float) a3_y[0] - (float) a3_y[1]) / ((float) a3_x[0] - (float) a3_x[1]); x1 = 0; - y1 = a3_pt_y[0] - (a3_pt_x[0] * slope); + y1 = a3_y[0] - (a3_x[0] * slope); x2 = canvas->w; - y2 = a3_pt_y[0] + ((canvas->w - a3_pt_x[0]) * slope); + y2 = a3_y[0] + ((canvas->w - a3_x[0]) * slope); - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 12, n_pt_persp_line_xor_callback); for (i = 0; i < 6; i++) { - x1 = a3_pt_x[0] + (((a3_pt_x[1] - a3_pt_x[0]) / 5) * i); - y1 = a3_pt_y[0] + ((x1 - a3_pt_x[0]) * slope); - x2 = a3_pt_x[2]; - y2 = a3_pt_y[2]; + x1 = a3_x[0] + (((a3_x[1] - a3_x[0]) / 5) * i); + y1 = a3_y[0] + ((x1 - a3_x[0]) * slope); + x2 = a3_x[2]; + y2 = a3_y[2]; - api->line((void *) api, which, canvas, NULL, + api->line((void *) api, tool, canvas, NULL, x1, y1, x2, y2, 12, n_pt_persp_line_xor_callback); }