Advertisement
TerusTheBird

masker: sdl_template.c

Jan 7th, 2025 (edited)
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 26.52 KB | Source Code | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <SDL/SDL.h>
  6.  
  7. #include "sdl_gen.h"
  8. #include "sdl_text.h"
  9.  
  10. #include "die_piss_logs.h"
  11.  
  12. #include "tga_v4.h"
  13.  
  14. typedef struct point_t point_t;
  15. struct point_t {
  16.     s32 x;
  17.     s32 y;
  18. };
  19.  
  20. typedef struct waypoint_t waypoint_t;
  21. struct waypoint_t {
  22.     u32     frame;
  23.     point_t pos;
  24.     u32     scale;
  25. };
  26.  
  27. // fourcc: 'wayp'
  28. #define FILE_MAGIC (0x77617970)
  29.  
  30. #define VID_WIDTH  (848U)
  31. #define VID_HEIGHT (480U)
  32.  
  33. #define FP_ONE (0x1000)
  34.  
  35. #define FP_MUL( n1, n2 )   ( S32( ( S64(n1) * S64(n2) ) / S64(FP_ONE) ) )
  36. #define FP_DIV( n1, n2 )   ( S32( ( S64(n1) * S64(FP_ONE) ) / S64(n2) ) )
  37.  
  38.  
  39.  
  40. #define SCREEN_WIDTH (VID_WIDTH)
  41. #define SCREEN_HEIGHT ((VID_HEIGHT)+32)
  42. #define DEFAULT_SCALE (FP_ONE)
  43.  
  44. #define SCALE_STEP (128U)
  45.  
  46. SDL_Surface* screen = NULL;
  47. SDL_Surface* screen_raw = NULL;
  48.  
  49. // cache of the current frame
  50. SDL_Surface* current_frame = NULL;
  51. // the frame number of the cached frame
  52. u32          current_frame_num = 0xFFFFFFFF;
  53.  
  54. SDL_Surface* mask = NULL;
  55. u32          mask_width = 1024U;
  56. u32          mask_target_width = 50U;
  57.  
  58. waypoint_t* waypoints = NULL;
  59.  
  60. SDL_Event event;
  61. _Bool done = False;
  62. _Bool updated = True;
  63. _Bool is_playing = False;
  64. int   is_playing_dir = 1;
  65. int   play_speed = 1;
  66. _Bool force_full_face = False;
  67. _Bool new_w = False;
  68. _Bool is_setting_scale = False;
  69. _Bool do_draw_lines = False;
  70. _Bool do_lighten = False;
  71.  
  72. // our current frame
  73. u32 frame_num = 0;
  74.  
  75. // the total frame count
  76. u32 frame_count = 0;
  77.  
  78. u32 scale_set_start_frame = 0;
  79. u32 scale_set_end_frame = 0;
  80.  
  81. u32 current_scale = DEFAULT_SCALE;
  82. u32 current_scale_divisor = 20U;
  83.  
  84. int mask_init( void ) {
  85.     SDL_Surface *temp, *temp2;
  86.    
  87.     temp = SDL_LoadBMP( "mask.bmp" );
  88.     if( !temp ) {
  89.         printf("Could load mask.bmp: %s\n", SDL_GetError());
  90.         return -1;
  91.     }
  92.    
  93.    
  94.     temp2 = SDL_ConvertSurface( temp, screen->format, SDL_SWSURFACE );
  95.     SDL_FreeSurface( temp ); temp = NULL;
  96.     if( !temp2 ) {
  97.         printf("Could load mask.bmp: %s\n", SDL_GetError());
  98.         return -2;
  99.     }
  100.    
  101.     if( mask ) {
  102.         SDL_FreeSurface( mask ); mask = NULL;
  103.     }
  104.     mask = temp2;
  105.    
  106.     mask_width = mask->w;
  107.    
  108.     return 0;
  109. }
  110.  
  111. #define WAYPOINT_DEFAULT ((waypoint_t){ .frame=0, .pos=(point_t){.x=0,.y=0}, .scale=DEFAULT_SCALE })
  112.  
  113. int waypoint_init( u32 frame_count ) {
  114.     if( waypoints ) return -1;
  115.     waypoints = (waypoint_t*)malloc( sizeof(waypoint_t) * frame_count );
  116.     if( !waypoints ) return -2;
  117.     memset( waypoints, 0, sizeof(waypoint_t) * frame_count );
  118.    
  119.     // you always need at least one
  120.     waypoints[0].scale = DEFAULT_SCALE;
  121.    
  122.     return 0;
  123. }
  124.  
  125. int waypoints_free( u32 frame_count ) {
  126.     if( !waypoints ) return -1;
  127.     memset( waypoints, 0, sizeof(waypoint_t) * frame_count );
  128.     free( waypoints ); waypoints = NULL;
  129.     return 0;
  130. }
  131.  
  132. int waypoint_add( u32 n, point_t pos, u32 scale ) {
  133.     if( !waypoints ) return -1;
  134.     waypoints[ n ].scale = scale; // this marks it as a good waypoint
  135.     waypoints[ n ].pos = pos;
  136.     waypoints[ n ].frame = n;
  137.     return 0;
  138. }
  139.  
  140. int waypoint_delete( u32 n ) {
  141.     if( !waypoints ) return -1;
  142.     if( n == 0 ) {
  143.         puts("you can't delete the first waypoint");
  144.         return -2;
  145.     }
  146.    
  147.     memset( &waypoints[ n ], 0, sizeof(waypoint_t) );
  148.     return 0;
  149. }
  150.  
  151. waypoint_t waypoint_get_first( void ) {
  152.     u32 n;
  153.     if( !waypoints ) return WAYPOINT_DEFAULT;
  154.     for( n = 0; n < frame_count; ++n ) {
  155.         if( waypoints[ n ].scale ) {
  156.             waypoints[ n ].frame = n;
  157.             return waypoints[ n ];
  158.         }
  159.     }
  160.     return WAYPOINT_DEFAULT;
  161. }
  162.  
  163. waypoint_t waypoint_get_last( void ) {
  164.     u32 i;
  165.     if( !waypoints ) return WAYPOINT_DEFAULT;
  166.     i = frame_count - 1;
  167.     while( True ) {
  168.         if( waypoints[ i ].scale ) {
  169.             waypoints[ i ].frame = i;
  170.             return waypoints[ i ];
  171.         }
  172.         if( i == 0 ) break;
  173.         --i;
  174.     }
  175.     return WAYPOINT_DEFAULT;
  176. }
  177.  
  178. waypoint_t waypoint_get_prev( u32 n ) {
  179.     if( !waypoints || n >= frame_count ) return WAYPOINT_DEFAULT;
  180.    
  181.     while( True ) {
  182.         if( waypoints[ n ].scale ) {
  183.             waypoints[ n ].frame = n;
  184.             return waypoints[ n ];
  185.         }
  186.         if( n == 0 ) break;
  187.         --n;
  188.     }
  189.     // if we didn't find one
  190.     return waypoint_get_first();
  191. }
  192.  
  193. waypoint_t waypoint_get_next( u32 n ) {
  194.     if( !waypoints ) return WAYPOINT_DEFAULT;
  195.    
  196.     while( n < frame_count ) {
  197.         if( waypoints[ n ].scale ) {
  198.             waypoints[ n ].frame = n;
  199.             return waypoints[ n ];
  200.         }
  201.         ++n;
  202.     }
  203.     // if we didn't find one
  204.     return waypoint_get_last();
  205. }
  206.  
  207. int scale_set_range( u32 n1, u32 n2, u32 scale ) {
  208.     if( !waypoints ) return -1;
  209.     while( n1 < n2 ) {
  210.         if( waypoints[ n1 ].scale ) {
  211.             waypoints[ n1 ].scale = scale;
  212.         }
  213.         ++n1;
  214.     }
  215.     return 0;
  216. }
  217.  
  218. void print_waypoint( waypoint_t w ) {
  219.     printf("frame %u, x %i, y %i, scale %08X\n",
  220.         w.frame,
  221.         w.pos.x,
  222.         w.pos.y,
  223.         w.scale
  224.     );
  225. }
  226.  
  227. point_t mouse_transform( point_t pos ) {
  228.     s64 x, y;
  229.     if( !screen || !screen_raw ) return pos;
  230.     x = pos.x; x *= screen->w; x /= screen_raw->w; pos.x = x;
  231.     y = pos.y; y *= screen->h; y /= screen_raw->h; pos.y = y;
  232.     return pos;
  233. }
  234.  
  235.  
  236.  
  237. _Bool file_exists( char* path ) {
  238.     FILE* fp;
  239.     if( !path ) return 0;
  240.     fp = fopen( path, "rb" );
  241.     if( fp ) {
  242.         fclose( fp );
  243.         return 1;
  244.     }
  245.     return 0;
  246. }
  247.  
  248. u32 get_frame_count( void ) {
  249.     char namebuf[ 32 ];
  250.     u32 count;
  251.     count = 0;
  252.     while( True ) {
  253.         memset( namebuf, 0, 32 );
  254.         snprintf( namebuf, 31, "../frames/frame_%06u.bmp", count );
  255.         if( file_exists( namebuf ) ) {
  256.             ++count;
  257.         } else {
  258.             break;
  259.         }
  260.     }
  261.     printf("found %u frames\n", count);
  262.     return count;
  263. }
  264.  
  265. u32 get_num_clipped( u32 n, s32 diff, u32 min, u32 max ) {
  266.     s64 N;
  267.     N = n;
  268.     N += diff;
  269.     if( N < min ) N = min;
  270.     if( N > max ) N = max;
  271.     return N;
  272. }
  273.  
  274. // load a new bitmap from the framestore
  275. int load_frame( u32 n ) {
  276.     SDL_Surface* temp;
  277.     SDL_Surface* temp_converted;
  278.     char namebuf[ 256 ];
  279.    
  280.     if( !screen ) return -1;
  281.    
  282.     if( current_frame_num == n ) return 0;
  283.    
  284.     memset( namebuf, 0, 256 );
  285.     snprintf( namebuf, 255, "../frames/frame_%06u.bmp", n );
  286.     temp = SDL_LoadBMP( namebuf );
  287.     if( !temp ) {
  288.         printf("Could not load %s\n", namebuf);
  289.         return -3;
  290.     }
  291.    
  292.     temp_converted = SDL_ConvertSurface( temp, screen->format, SDL_SWSURFACE );
  293.     SDL_FreeSurface( temp ); temp = NULL;
  294.     if( !temp_converted ) {
  295.         return -4;
  296.     }
  297.    
  298.     if( current_frame ) {
  299.         SDL_FreeSurface( current_frame ); current_frame = NULL;
  300.     }
  301.    
  302.     current_frame = temp_converted;
  303.     current_frame_num = n;
  304.     printf("Loaded %s\n", namebuf);
  305.     fflush( stdout );
  306.    
  307.     return 0;
  308. }
  309.  
  310. u32 interp_fixed( u32 pos1, u32 pos_cur, u32 pos2, u32 pos1val, u32 pos2val ) {
  311.     s64 P, O, H, L; // P=percentage, O=one(or offset), H=half, L=length
  312.     if( pos1 == pos2 ) return pos1val;
  313.     if( pos1 > pos2 ) {
  314.         u32 T;
  315.         T = pos1; pos1 = pos2; pos2 = T;
  316.         T = pos1val; pos1val = pos2val; pos2val = T;
  317.     }
  318.     if( pos_cur <= pos1 ) return pos1val;
  319.     if( pos_cur >= pos2 ) return pos2val;
  320.     O = pos2 - pos1;  H = O>>1;
  321.     P = pos_cur - pos1;
  322.     L = pos2val; L -= pos1val;
  323.    
  324.     return pos1val + ( ( ( L * P ) + H ) / O );
  325. }
  326.  
  327. float interp( u32 pos1, u32 pos_cur, u32 pos2,  float pos1val, float pos2val ) {
  328.     float percentage;
  329.     if( pos1 == pos2 ) return pos1val;
  330.     if( pos1 > pos2 ) {
  331.         float TF;
  332.         u32 T;
  333.         T = pos1; pos1 = pos2; pos2 = T;
  334.         TF = pos1val; pos1val = pos2val; pos2val = TF;
  335.     }
  336.     if( pos_cur <= pos1 ) return pos1val;
  337.     if( pos_cur >= pos2 ) return pos2val;
  338.     percentage = ((float)( pos_cur - pos1 )) / ((float)( pos2 - pos1 ));
  339.     return pos1val + ( pos2val - pos1val ) * percentage;
  340. }
  341.  
  342. waypoint_t get_pos_scale( u32 n ) {
  343.     waypoint_t w1, w2, out;
  344.     w1 = waypoint_get_prev( n );
  345.     w2 = waypoint_get_next( n );
  346.    
  347.     out.pos.x = interp( w1.frame, n, w2.frame,  w1.pos.x, w2.pos.x );
  348.     out.pos.y = interp( w1.frame, n, w2.frame,  w1.pos.y, w2.pos.y );
  349.     out.scale = interp_fixed( w1.frame, n, w2.frame,  w1.scale, w2.scale );
  350.     return out;
  351. }
  352.  
  353. u32 fp_mul_scale( u64 n1, u64 n2 ) {
  354.     n1 *= n2;
  355.     n1 += ( FP_ONE / 2U ); // round
  356.     n1 /= FP_ONE;
  357.     return n1;
  358. }
  359.  
  360. int fmul( float n, float m ) {
  361.     return ( (n*m)+0.5f );
  362. }
  363.  
  364. int draw_mask( SDL_Surface* surf, int x, int y, u32 scale, u32 mode ) {
  365.     u32 S;
  366.     if( mode == 0 ) return 0;
  367.     if( mode == 1 || mask == NULL ) {
  368.         // render a circle
  369.         S = fp_mul_scale( mask_width / 2U, scale );
  370.         S /= current_scale_divisor;
  371.         SDL_Circle( surf, x, y, S, c_red );
  372.     } else if( mode == 2 ) {
  373.         u32 S;
  374.         // render the full face
  375.         SDL_Surface* scaled;
  376.         S = fp_mul_scale( mask->w, scale );
  377.         S /= current_scale_divisor;
  378.         scaled = scale_surface( mask, NULL, S, S );
  379.         if( scaled ) {
  380.             SDL_Rect r;
  381.             r.x = scaled->w; r.x /= 2; r.x += x;
  382.             r.y = scaled->h; r.y /= 2; r.y += y;
  383.             r = (SDL_Rect){ x - ( scaled->w / 2 ), y - ( scaled->h / 2 ), 0, 0 };
  384.             SDL_SetColorKey( scaled, SDL_SRCCOLORKEY, color_to_surf( scaled, c_trans ) );
  385.             SDL_BlitSurface( scaled, NULL, surf, &r );
  386.             SDL_FreeSurface( scaled ); scaled = NULL;
  387.         }
  388.     }
  389.     return 0;
  390. }
  391.  
  392.  
  393. u32 get_waypoint_count( void ) {
  394.     u32 i, wc;
  395.     if( !waypoints ) return 0;
  396.     wc = 0;
  397.     for( i = 0; i < frame_count; ++i ) {
  398.         if( waypoints[ i ].scale ) {
  399.             waypoints[ i ].frame = i;
  400.             ++wc;
  401.         }
  402.     }
  403.     return wc;
  404. }
  405.  
  406. int draw_waypoints( SDL_Surface* surf ) {
  407.     u32 last, i;
  408.     if( !waypoints ) return -1;
  409.     last = 0;
  410.     for( i = 1; i < frame_count; ++i ) {
  411.         if( waypoints[ i ].scale ) {
  412.             SDL_Line(
  413.                 surf,
  414.                 waypoints[ last ].pos.x,
  415.                 waypoints[ last ].pos.y,
  416.                 waypoints[ i ].pos.x,
  417.                 waypoints[ i ].pos.y,
  418.                 c_white
  419.             );
  420.             last = i;
  421.         }
  422.     }
  423.    
  424.     return 0;
  425. }
  426.  
  427.  
  428. rgb96_t pixel_get_box( SDL_Surface* surf, long x, long y, u32 rad, u32* count ) {
  429.     u32 dx, dy; rgb96_t r;
  430.     r = (rgb96_t){.r=0,.g=0,.b=0};
  431.     if( !surf ) return r;
  432.     if( !rad ) return pixel_high_get( surf, x, y );
  433.     rad = ( rad << 1 ) | 1;
  434.     if( count ) *count = 0;
  435.     for( dy = 0; dy < rad; ++dy ) {
  436.         for( dx = 0; dx < rad; ++dx ) {
  437.             r = pixel_high_add( r, pixel_high_get( surf, ( x + dx ) - ( rad >> 1 ), ( y + dy ) - ( rad >> 1 ) ) );
  438.             if( count ) ++*count;
  439.         }
  440.     }
  441.     return r;
  442. }
  443.  
  444. s32 fp_scale( s32 n, s32 min, s32 one, s32 d ) {
  445.     s64 r;
  446.     r = n; r -= min; r *= one, r /= d;
  447.     if( r < 0 ) r = 0;
  448.     if( r > one ) r = one;
  449.     return (s32)r;
  450. }
  451.  
  452. tga_t* tga_mask = NULL;
  453.  
  454. void blast_frame( SDL_Surface* surf ) {
  455.     u32 min, max, x, y, diff;
  456.     u32 last;
  457.     if( !surf ) return;
  458.     if( !tga_mask ) return;
  459.    
  460.     // uh this makes the frame lighter
  461.     min = 0xFFFFFFFF;
  462.     max = 0;
  463.     last = 0;
  464.     for( y = 0; y < surf->h; ++y ) {
  465.         for( x = 0; x < surf->w; ++x ) {
  466.             u32 v;
  467.             if( tga_pixel_get8( tga_mask, x, y ) ) {
  468.                 v = last;
  469.             } else {
  470.                 v = pixel_high_gray( pixel_get_box( surf, x, y, 2, NULL ) );
  471.             }
  472.             //v = pixel_high_gray( pixel_high_get( surf, x, y ) );
  473.             if( v < min ) min = v;
  474.             if( v > max ) max = v;
  475.             last = v;
  476.         }
  477.     }
  478.     min /= 25;
  479.     max /= 25;
  480.     diff = max - min;
  481.     printf("min %u  max %u  diff %u\n", min, max, diff);
  482.     for( y = 0; y < surf->h; ++y ) {
  483.         for( x = 0; x < surf->w; ++x ) {
  484.             rgb96_t c;
  485.             c = pixel_high_get( surf, x, y );
  486.             c.r = fp_scale( c.r, min, 0xFFF, diff );
  487.             c.g = fp_scale( c.g, min, 0xFFF, diff );
  488.             c.b = fp_scale( c.b, min, 0xFFF, diff );
  489.             pixel_high_put( surf, x, y, c );
  490.         }
  491.     }
  492. }
  493.  
  494. int draw_screen( SDL_Surface* surf, u32 n, int draw_face, _Bool draw_lines, _Bool lighten ) {
  495.     waypoint_t pos;
  496.     SDL_Surface* temp;
  497.     if( !surf ) return -1;
  498.     temp = surf_new( VID_WIDTH, VID_HEIGHT );
  499.     if( !temp ) return -2;
  500.    
  501.     if( load_frame( n ) < 0 ) return -3;
  502.    
  503.    
  504.     SDL_BlitSurface( current_frame, NULL, temp, NULL );
  505.    
  506.     if( lighten ) {
  507.         blast_frame( temp );
  508.     }
  509.    
  510.     if( draw_lines ) {
  511.         draw_waypoints( temp );
  512.     }
  513.    
  514.     pos = get_pos_scale( n );
  515.     if( draw_face > 0 ) {
  516.         draw_mask( temp, pos.pos.x, pos.pos.y, pos.scale, draw_face );
  517.     }
  518.    
  519.     SDL_BlitSurface( temp, NULL, surf, NULL );
  520.    
  521.     SDL_FreeSurface( temp ); temp = NULL;
  522.     return 0;
  523. }
  524.  
  525. void file_write_u16( FILE* fp, u16 n ) {
  526.     if( !fp ) return;
  527.     fputc( n >> 8, fp );
  528.     fputc( n&255U, fp );
  529. }
  530.  
  531. void file_write_u32( FILE* fp, u32 n ) {
  532.     if( !fp ) return;
  533.     fputc( ( n >> 24 ) & 0xFF, fp );
  534.     fputc( ( n >> 16 ) & 0xFF, fp );
  535.     fputc( ( n >>  8 ) & 0xFF, fp );
  536.     fputc( ( n       ) & 0xFF, fp );
  537. }
  538.  
  539. void file_write_u64( FILE* fp, u64 n ) {
  540.     if( !fp ) return;
  541.     fputc( ( n >> 56 ) & 0xFF, fp );
  542.     fputc( ( n >> 48 ) & 0xFF, fp );
  543.     fputc( ( n >> 40 ) & 0xFF, fp );
  544.     fputc( ( n >> 32 ) & 0xFF, fp );
  545.     fputc( ( n >> 24 ) & 0xFF, fp );
  546.     fputc( ( n >> 16 ) & 0xFF, fp );
  547.     fputc( ( n >>  8 ) & 0xFF, fp );
  548.     fputc( ( n >>  0 ) & 0xFF, fp );
  549. }
  550.  
  551. u16 file_read_u16( FILE* fp ) {
  552.     u16 n;
  553.     if( !fp ) return 0;
  554.     n = fgetc( fp ); n <<= 8; n |= fgetc( fp );
  555.     return n;
  556. }
  557.  
  558. u32 file_read_u32( FILE* fp ) {
  559.     u32 n;
  560.     if( !fp ) return 0;
  561.     n  = fgetc( fp ) & 0xFF; n <<= 8;
  562.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  563.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  564.     n |= fgetc( fp ) & 0xFF;
  565.     return n;
  566. }
  567.  
  568. u64 file_read_u64( FILE* fp ) {
  569.     u64 n;
  570.     if( !fp ) return 0ULL;
  571.     n  = fgetc( fp ) & 0xFF; n <<= 8;
  572.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  573.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  574.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  575.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  576.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  577.     n |= fgetc( fp ) & 0xFF; n <<= 8;
  578.     n |= fgetc( fp ) & 0xFF;
  579.     return n;
  580. }
  581.  
  582. void file_waypoint_write( FILE* fp, waypoint_t w ) {
  583.     u64 n;
  584.     if( !fp ) return;
  585.     n = ( w.frame ) & 0xFFFFFF;
  586.     n <<= 12; n |= ( w.pos.x ) &    0xFFF;
  587.     n <<= 12; n |= ( w.pos.y ) &    0xFFF;
  588.     n <<= 16; n |= ( w.scale ) &   0xFFFF;
  589.     file_write_u64( fp, n );
  590. }
  591.  
  592. waypoint_t file_waypoint_read( FILE* fp ) {
  593.     u64 n;
  594.     waypoint_t w;
  595.     n = file_read_u64( fp );
  596.     w.scale = n &   0xFFFF; n >>= 16;
  597.     w.pos.y = n &    0xFFF; n >>= 12;
  598.     w.pos.x = n &    0xFFF; n >>= 12;
  599.     w.frame = n & 0xFFFFFF;
  600.     if( w.scale == 0 ) {
  601.         w.scale = 0x10000;
  602.     }
  603.     return w;
  604. }
  605.  
  606.  
  607. // ----------------------------------- buttons --------------------------------------
  608.  
  609. void btn_waypoint_save( void ) {
  610.     u32 waypoint_count, i;
  611.     char out_path[ 8192 ];
  612.     FILE* fp;
  613.     if( !waypoints ) return;
  614.    
  615.     if( !dialog_save( "Save waypoints", out_path, 8192 ) ) return;
  616.    
  617.     // get the amount of waypoints
  618.     waypoint_count = 0;
  619.     for( i = 0; i < frame_count; ++i ) {
  620.         if( waypoints[ i ].scale ) {
  621.             ++waypoint_count;
  622.         }
  623.     }
  624.    
  625.     // open up the file
  626.     fp = fopen( out_path, "wb" );
  627.     if( !fp ) {
  628.         printf( "Couldn't open %s for saving\n", out_path );
  629.         return;
  630.     }
  631.    
  632.     file_write_u32( fp, FILE_MAGIC );
  633.     file_write_u32( fp, waypoint_count );
  634.     file_write_u32( fp, frame_num );
  635.     file_write_u16( fp, current_scale & 0xFFFF );
  636.     file_write_u16( fp, current_scale_divisor & 0xFFFF );
  637.    
  638.     for( i = 0; i < frame_count; ++i ) {
  639.         if( waypoints[ i ].scale ) {
  640.             file_waypoint_write( fp, waypoints[ i ] );
  641.         }
  642.     }
  643.    
  644.     fclose( fp ); fp = NULL;
  645.     printf("Saved %u waypoints to %s\n", waypoint_count, out_path);
  646. }
  647.  
  648.  
  649. void btn_waypoint_load( void ) {
  650.     FILE* fp;
  651.     u32 count, magic, cur_frame, cur_scale, i, loaded_count, div;
  652.     char in_path[ 8192 ];
  653.    
  654.     if( !waypoints ) return;
  655.    
  656.     if( !dialog_load( "Load waypoints", in_path, 8192 ) ) return;
  657.     fp = fopen( in_path, "rb" );
  658.     if( !fp ) {
  659.         printf("Cannot open %s\n", in_path);
  660.         return;
  661.     }
  662.    
  663.     magic = file_read_u32( fp );
  664.     if( magic != FILE_MAGIC ) {
  665.         puts("This is not a waypoint file");
  666.         fclose( fp ); fp = NULL;
  667.         return;
  668.     }
  669.    
  670.     count = file_read_u32( fp );
  671.     if( count == 0 ) {
  672.         puts("Waypoint file has no waypoints");
  673.         fclose( fp ); fp = NULL;
  674.         return;
  675.     }
  676.    
  677.     cur_frame = file_read_u32( fp );
  678.     cur_scale = file_read_u16( fp );
  679.     div = file_read_u16( fp );
  680.    
  681.     memset( waypoints, 0, sizeof(waypoint_t) * frame_count );
  682.     waypoints[0] = WAYPOINT_DEFAULT;
  683.    
  684.     loaded_count = 0;
  685.     for( i = 0; i < count; ++i ) {
  686.         waypoint_t w;
  687.         w = file_waypoint_read( fp );
  688.         if( w.frame < frame_count ) {
  689.             waypoints[ w.frame ] = w;
  690.             ++loaded_count;
  691.         }
  692.     }
  693.    
  694.     fclose( fp ); fp = NULL;
  695.    
  696.     frame_num = cur_frame;
  697.     current_scale = cur_scale;
  698.     if( div == 0 ) {
  699.         puts("Scale divisor is zero");
  700.     } else {
  701.         current_scale_divisor = div;
  702.     }
  703.     printf("Loaded %u waypoints from %s\n", loaded_count, in_path);
  704. }
  705.  
  706.  
  707. void btn_goto_start( void ) {
  708.     frame_num = 0;
  709. }
  710.  
  711. void btn_goto_end( void ) {
  712.     frame_num = frame_count - 1;
  713. }
  714.  
  715. void btn_goto_waypoint_first( void ) {
  716.     waypoint_t w;
  717.     w = waypoint_get_first();
  718.     frame_num = w.frame;
  719. }
  720.  
  721. void btn_goto_waypoint_last( void ) {
  722.     waypoint_t w;
  723.     w = waypoint_get_last();
  724.     frame_num = w.frame;
  725. }
  726.  
  727. void video_resize( u32 w_new, u32 h_new ) {
  728.     w_new = h_new; w_new *= SCREEN_WIDTH; w_new += SCREEN_WIDTH / 2; w_new /= SCREEN_HEIGHT;
  729.     screen_raw = SDL_SetVideoMode( w_new, h_new, 24, SDL_SWSURFACE | SDL_RESIZABLE );
  730.     updated=True;
  731. }
  732.  
  733. void btn_zoom1( void ) {
  734.     video_resize( SCREEN_WIDTH, SCREEN_HEIGHT );
  735. }
  736.  
  737. void btn_waypoint_delete( void ) {
  738.     waypoint_delete( frame_num );
  739. }
  740.  
  741. void btn_scale_set_range_start( void ) {
  742.     scale_set_start_frame = frame_num;
  743. }
  744.  
  745. void btn_scale_set_range_end( void ) {
  746.     scale_set_end_frame = frame_num;
  747. }
  748.  
  749. void btn_scale_set_range_do( void ) {
  750.     u32 i;
  751.     if( !waypoints ) return;
  752.     if( scale_set_start_frame < 0 ) scale_set_start_frame = 0;
  753.     if( scale_set_start_frame > frame_count ) scale_set_start_frame = frame_count;
  754.     if( scale_set_end_frame < 0 ) scale_set_end_frame = 0;
  755.     if( scale_set_end_frame > frame_count ) scale_set_end_frame = frame_count;
  756.    
  757.     if( scale_set_end_frame < scale_set_start_frame ) {
  758.         i = scale_set_end_frame; scale_set_end_frame = scale_set_start_frame; scale_set_start_frame = i;
  759.     }
  760.    
  761.     for( i = scale_set_start_frame; i < scale_set_end_frame; ++i ) {
  762.         if( waypoints[ i ].scale ) {
  763.             waypoints[ i ].frame = i;
  764.             waypoints[ i ].scale = current_scale;
  765.         }
  766.     }
  767. }
  768.  
  769. int screen_flush( SDL_Surface* in, SDL_Surface* out );
  770.  
  771. void emit_frames( _Bool lightened ) {
  772.     u32 i;
  773.     if( !waypoints ) return;
  774.     for( i = 0; i < frame_count; ++i ) {
  775.         SDL_Surface* out;
  776.         out = surf_new( VID_WIDTH, VID_HEIGHT );
  777.         if( out ) {
  778.             char out_fname[ 64 ];
  779.             draw_screen( out, i, 2, 0, lightened );
  780.            
  781.             memset( out_fname, 0, 64 );
  782.             snprintf( out_fname, 63, "../frames_out/out_%06u.tga", i );
  783.             save_to_tga( out, out_fname );
  784.            
  785.             screen_flush( out, screen_raw );
  786.             SDL_UpdateRect( screen_raw, 0, 0, screen_raw->w, screen_raw->h );
  787.             printf("Saved %s\n", out_fname);
  788.             SDL_FreeSurface( out ); out = NULL;
  789.         }
  790.     }
  791. }
  792.  
  793. void btn_emit_frames( void ) {
  794.     emit_frames( 0 );
  795.     puts("Emit frames");
  796. }
  797.  
  798. void btn_emit_frames_bright( void ) {
  799.     emit_frames( 1 );
  800.     puts("Emit frames bright");
  801. }
  802.  
  803.  
  804.  
  805.  
  806. typedef struct button_t button_t;
  807. struct button_t {
  808.     int x;
  809.     int y;
  810.     const char* str;
  811.     void (*func)(void);
  812. };
  813.  
  814.  
  815. button_t buttons[] = {
  816.     (button_t){  160,  0, "save waypoints",  btn_waypoint_save },
  817.     (button_t){  160, 16, "load waypoints",  btn_waypoint_load },
  818.     (button_t){    0, 16, "Fbgn",            btn_goto_start },
  819.     (button_t){   29, 16, "Fend",            btn_goto_end },
  820.     (button_t){ 29*2, 16, "Wbgn",            btn_goto_waypoint_first },
  821.     (button_t){ 29*3, 16, "Wend",            btn_goto_waypoint_last },
  822.     (button_t){  132, 16, "1x",              btn_zoom1 },
  823.     (button_t){  256,  0, "delete waypoint", btn_waypoint_delete },
  824.    
  825.     (button_t){  256, 16, "RangeStart",      btn_scale_set_range_start },
  826.     (button_t){  322, 16, "RangeEnd",        btn_scale_set_range_end },
  827.     (button_t){  352,  0, "RangeSet",        btn_scale_set_range_do },
  828.     (button_t){  385, 16, "Emit",            btn_emit_frames },
  829.     (button_t){  420, 16, "Emit bright",     btn_emit_frames_bright }
  830. };
  831. #define BUTTON_COUNT  (sizeof(buttons) / sizeof(buttons[0]))
  832.  
  833.  
  834. int click_buttons( point_t mouse, int off_x, int off_y ) {
  835.     int i;
  836.     for( i = 0; i < BUTTON_COUNT; ++i ) {
  837.         int x, y, w, h;
  838.         if( !buttons[i].func ) continue;
  839.         w = h = 0;
  840.         if( buttons[i].str != NULL ) {
  841.             text_len_get( buttons[i].str, &w, &h );
  842.         }
  843.         w += 4; h += 4;
  844.         x = buttons[i].x + off_x;
  845.         y = buttons[i].y + off_y;
  846.         if( mouse.x >= x && mouse.x < ( x + w ) && mouse.y >= y && mouse.y < ( y + h ) ) {
  847.             buttons[i].func();
  848.             return i;
  849.         }
  850.     }
  851.     return -1;
  852. }
  853.  
  854. int draw_button( SDL_Surface* surf, int x, int y, const char* str ) {
  855.     int sl;
  856.     SDL_Rect r;
  857.     if( !surf ) return -1;
  858.     sl = 0;
  859.     if( str ) {
  860.         sl = strlen( str );
  861.         sl *= 6;
  862.     }
  863.     r.w = 2+sl+2;   r.h = 2+8+2;   r.x = x;   r.y = y;
  864.     SDL_FillRect( surf, &r, color_to_surf( surf, c_white ) );
  865.     r.x += 1;  r.y += 1;  r.w -= 2;  r.h -= 2;
  866.     SDL_FillRect( surf, &r, color_to_surf( surf, c_black ) );
  867.     if( str )
  868.         text_print_str( x+2, y+2, (char*)str, c_white, surf );
  869.     return 0;
  870. }
  871.  
  872. int draw_buttons( SDL_Surface* surf, u32 y ) {
  873.     int i;
  874.     for( i = 0; i < BUTTON_COUNT; ++i ) {
  875.         draw_button( surf, buttons[ i ].x, buttons[ i ].y + y, buttons[ i ].str );
  876.     }
  877.     return 0;
  878. }
  879.  
  880. void timecode_print( int x, int y, u32 n, color_t color, SDL_Surface* t ) {
  881.     u32 mins, sex, frames;
  882.     char temp_buf[ 64 ];
  883.     if( !t ) return;
  884.     memset( temp_buf, 0, 64 );
  885.     mins   =   n / ( 30U * 60U );
  886.     sex    = ( n / 30U ) % 60U;
  887.     frames =   n % 30U;
  888.     snprintf( temp_buf, 63, "frame %i %02i:%02i.%02i", n, mins, sex, frames );
  889.     text_print_str( x, y, temp_buf, color, t );
  890. }
  891.  
  892. int draw_hud( SDL_Surface* surf ) {
  893.     int x, y;
  894.     waypoint_t w;
  895.     if( !surf ) return -1;
  896.    
  897.     SDL_Clear_rect_easy( surf, 0, VID_HEIGHT, VID_WIDTH, 32, c_gray25 );
  898.    
  899.     w = get_pos_scale( frame_num );
  900.     x = 0; y = VID_HEIGHT+1;
  901.    
  902.     draw_mask( surf, 700, y+16, current_scale, 1 );
  903.    
  904.     if( is_setting_scale )
  905.         text_print_char( 118, y+16, 'S', c_white, surf );
  906.    
  907.     timecode_print( x, y, frame_num, c_white, surf );
  908.     y += 8;
  909.     text_print__str_u32_u32( x, y, "scale", current_scale, w.scale, c_white, surf );
  910.    
  911.     y=VID_HEIGHT+1;
  912.     if( waypoints ) {
  913.         if( waypoints[ frame_num ].scale ) {
  914.             text_print_str( 420, y, "Frame has waypoint", c_white, surf );
  915.             y+=8;
  916.         }
  917.     }
  918.    
  919.     text_print__str_int_str_int( 420, y, "WS S", scale_set_start_frame, "| WS E", scale_set_end_frame, c_white, surf );
  920.    
  921.     if( draw_buttons( surf, VID_HEIGHT+1 ) < 0 ) return -2;
  922.    
  923.     return 0;
  924. }
  925.  
  926. int screen_flush( SDL_Surface* in, SDL_Surface* out ) {
  927.     if( !in ) return -1;
  928.     if( !out ) return -2;
  929.    
  930.     if( in->w == out->w && in->h == out->h ) {
  931.         //scale_surface( in, out, out->w, out->h );
  932.         SDL_BlitSurface( in, NULL, out, NULL );
  933.     } else {
  934.         scale_surface( in, out, out->w, out->h );
  935.     }
  936.     return 0;
  937. }
  938.  
  939.  
  940. int main( int argc, char** argv ) {
  941.     if( SDL_WasInit( SDL_INIT_VIDEO ) )
  942.         return 0;
  943.     SDL_Init(SDL_INIT_VIDEO);
  944.    
  945.     screen = surf_new( SCREEN_WIDTH, SCREEN_HEIGHT );
  946.     if( !screen ) {
  947.         SDL_Quit();
  948.         return 0;
  949.     }
  950.    
  951.     screen_raw = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 24, SDL_SWSURFACE | SDL_RESIZABLE );
  952.     if( !screen_raw ) {
  953.         SDL_FreeSurface( screen ); screen = NULL;
  954.         SDL_Quit();
  955.         return 0;
  956.     }
  957.     SDL_Clear( screen, c_gray25 );
  958.    
  959.     frame_count = get_frame_count();
  960.     if( !frame_count ) {
  961.         SDL_FreeSurface( screen ); screen = NULL;
  962.         SDL_Quit();
  963.         return 0;
  964.     }
  965.    
  966.     if( waypoint_init( frame_count ) < 0 ) {
  967.         puts("waypoint_init fail" );
  968.         abort();
  969.     }
  970.     if( mask_init() < 0 ) {
  971.         puts("mask_init fail");
  972.         abort();
  973.     }
  974.    
  975.     tga_mask = tga_load( "shitmask.tga" );
  976.     if( !tga_mask ) abort();
  977.    
  978.     done = 0;
  979.     while( !done ) {
  980.         while(SDL_PollEvent(&event)) {
  981.             if( event.type == SDL_QUIT )
  982.                 done = 1;
  983.             if( event.type == SDL_VIDEORESIZE ) {
  984.                 video_resize( event.resize.w, event.resize.h );
  985.             }
  986.             #define K (event.key.keysym.sym)
  987.             if( event.type == SDL_KEYDOWN ) {
  988.                 if( K == SDLK_RIGHT ) {
  989.                     frame_num = get_num_clipped( frame_num,   play_speed,   0, frame_count-1 );
  990.                     updated=True;
  991.                 }
  992.                 if( K == SDLK_LEFT ) {
  993.                     frame_num = get_num_clipped( frame_num,  -play_speed,   0, frame_count-1 );
  994.                     updated=True;
  995.                 }
  996.                 if( K == SDLK_p ) {
  997.                     is_playing = True;
  998.                 }
  999.                 if( K == SDLK_o ) {
  1000.                     is_playing_dir = -1;
  1001.                 }
  1002.                 if( K == SDLK_f ) {
  1003.                     play_speed = 30;
  1004.                 }
  1005.                 if( K == SDLK_u ) {
  1006.                     force_full_face = True;
  1007.                     updated = True;
  1008.                 }
  1009.                 if( K == SDLK_v ) {
  1010.                     new_w = True;
  1011.                     updated = True;
  1012.                 }
  1013.                 if( K == SDLK_c ) {
  1014.                     is_setting_scale = True;
  1015.                     updated = True;
  1016.                 }
  1017.                 if( K == SDLK_l ) {
  1018.                     do_draw_lines = True;
  1019.                     updated = True;
  1020.                 }
  1021.                
  1022.                 if( K == SDLK_UP ) {
  1023.                     current_scale += SCALE_STEP;
  1024.                     updated=True;
  1025.                 }
  1026.                 if( K == SDLK_DOWN ) {
  1027.                     current_scale -= SCALE_STEP;
  1028.                     updated=True;
  1029.                 }
  1030.                 if( K == SDLK_k ) {
  1031.                     do_lighten = True;
  1032.                     updated = True;
  1033.                 }
  1034.                 //printf( "SDL_KEYDOWN %i\n", K );
  1035.             }
  1036.             if( event.type == SDL_KEYUP ) {
  1037.                 if( K == SDLK_p ) {
  1038.                     is_playing = False;
  1039.                     updated = True;
  1040.                 }
  1041.                 if( K == SDLK_o ) {
  1042.                     is_playing_dir = 1;
  1043.                 }
  1044.                 if( K == SDLK_f ) {
  1045.                     play_speed = 1;
  1046.                 }
  1047.                 if( K == SDLK_u ) {
  1048.                     force_full_face = False;
  1049.                     updated = True;
  1050.                 }
  1051.                 if( K == SDLK_v ) {
  1052.                     new_w = False;
  1053.                     updated = True;
  1054.                 }
  1055.                 if( K == SDLK_c ) {
  1056.                     is_setting_scale = False;
  1057.                     updated = True;
  1058.                 }
  1059.                 if( K == SDLK_l ) {
  1060.                     do_draw_lines = False;
  1061.                     updated = True;
  1062.                 }
  1063.                 if( K == SDLK_k ) {
  1064.                     do_lighten = False;
  1065.                     updated = True;
  1066.                 }
  1067.                 //printf( "SDL_KEYUP %i\n", K );
  1068.             }
  1069.             #undef K
  1070.             if( event.type == SDL_MOUSEBUTTONDOWN ) {
  1071.                 point_t pos;
  1072.                 pos.x = event.button.x;
  1073.                 pos.y = event.button.y;
  1074.                 pos = mouse_transform( pos );
  1075.                 if( event.button.button == 1 ) {
  1076.                     if( event.button.y >= VID_HEIGHT ) {
  1077.                         click_buttons( pos, 0, VID_HEIGHT+1 );
  1078.                         updated = True;
  1079.                     }
  1080.                 } else if( event.button.button == 4 ) {
  1081.                     // wheel up
  1082.                     if( is_setting_scale ) {
  1083.                         current_scale += SCALE_STEP;
  1084.                     } else {
  1085.                         frame_num = get_num_clipped( frame_num,   play_speed,   0, frame_count-1 );
  1086.                     }
  1087.                     updated = True;
  1088.                 } else if( event.button.button == 5 ) {
  1089.                     // wheel down
  1090.                     if( is_setting_scale ) {
  1091.                         current_scale -= SCALE_STEP;
  1092.                         // it can't be zero since that means "no waypoint is here"
  1093.                         if( !current_scale ) current_scale = DEFAULT_SCALE;
  1094.                     } else {
  1095.                         frame_num = get_num_clipped( frame_num,  -play_speed,   0, frame_count-1 );
  1096.                     }
  1097.                     updated = True;
  1098.                 }
  1099.             }
  1100.         }
  1101.        
  1102.         if( is_playing ) {
  1103.             frame_num = get_num_clipped( frame_num,  play_speed*is_playing_dir,   0, frame_count-1 );
  1104.             updated=True;
  1105.         }
  1106.         if( new_w ) {
  1107.             updated = True;
  1108.         }
  1109.        
  1110.         if( updated ) {
  1111.             int mask_state;
  1112.             if( current_scale == 0 ) {
  1113.                 current_scale = FP_ONE;
  1114.             }
  1115.            
  1116.             if( new_w ) {
  1117.                 point_t mouse_pos;
  1118.                 SDL_GetMouseState( &mouse_pos.x, &mouse_pos.y );
  1119.                 mouse_pos = mouse_transform( mouse_pos );
  1120.                 waypoint_add( frame_num, mouse_pos, current_scale );
  1121.             }
  1122.            
  1123.             mask_state = 1; mask_state += force_full_face;
  1124.             draw_screen( screen, frame_num, mask_state, do_draw_lines, do_lighten );
  1125.             draw_hud( screen );
  1126.            
  1127.             screen_flush( screen, screen_raw );
  1128.             SDL_UpdateRect( screen_raw, 0, 0, screen_raw->w, screen_raw->h );
  1129.             updated=False;
  1130.         }
  1131.         SDL_Delay(32);
  1132.     }
  1133.    
  1134.     waypoints_free( frame_count );
  1135.    
  1136.    
  1137.     tga_mask = tga_free( tga_mask );
  1138.     SDL_Quit();
  1139.     return 0;
  1140. }
  1141.  
  1142.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement