2015-03-15 20:51:56 +01:00
/*! \file utils.c
* \ brief Helper functions .
2012-12-24 19:41:12 +01:00
*/
/*
* Copyright ( c ) Sebastian Krzyszkowiak < dos @ dosowisko . net >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
2012-12-26 23:48:05 +01:00
# include <allegro5/allegro_primitives.h>
2016-06-27 21:20:02 +02:00
# include <allegro5/allegro_ttf.h>
2016-09-08 00:32:21 +02:00
# include <stdio.h>
# include <string.h>
# include <math.h>
# include "internal.h"
2012-12-24 19:41:12 +01:00
# include "config.h"
# include "utils.h"
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT void DrawVerticalGradientRect ( float x , float y , float w , float h , ALLEGRO_COLOR top , ALLEGRO_COLOR bottom ) {
2012-12-24 19:41:12 +01:00
ALLEGRO_VERTEX v [ ] = {
2016-07-02 23:23:08 +02:00
{ . x = x , . y = y , . z = 0 , . color = top } ,
{ . x = x + w , . y = y , . z = 0 , . color = top } ,
{ . x = x , . y = y + h , . z = 0 , . color = bottom } ,
{ . x = x + w , . y = y + h , . z = 0 , . color = bottom } } ;
2012-12-24 19:41:12 +01:00
al_draw_prim ( v , NULL , NULL , 0 , 4 , ALLEGRO_PRIM_TRIANGLE_STRIP ) ;
}
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT void DrawHorizontalGradientRect ( float x , float y , float w , float h , ALLEGRO_COLOR left , ALLEGRO_COLOR right ) {
2012-12-24 19:41:12 +01:00
ALLEGRO_VERTEX v [ ] = {
2016-07-02 23:23:08 +02:00
{ . x = x , . y = y , . z = 0 , . color = left } ,
{ . x = x + w , . y = y , . z = 0 , . color = right } ,
{ . x = x , . y = y + h , . z = 0 , . color = left } ,
{ . x = x + w , . y = y + h , . z = 0 , . color = right } } ;
2012-12-24 19:41:12 +01:00
al_draw_prim ( v , NULL , NULL , 0 , 4 , ALLEGRO_PRIM_TRIANGLE_STRIP ) ;
}
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT void DrawTextWithShadow ( ALLEGRO_FONT * font , ALLEGRO_COLOR color , float x , float y , int flags , char const * text ) {
2016-09-08 01:42:48 +02:00
al_draw_text ( font , al_map_rgba ( 0 , 0 , 0 , 128 ) , x + 1 , y + 1 , flags , text ) ;
al_draw_text ( font , color , x , y , flags , text ) ;
2012-12-24 19:41:12 +01:00
}
2016-09-08 01:42:48 +02:00
SYMBOL_EXPORT int DrawWrappedText ( ALLEGRO_FONT * font , ALLEGRO_COLOR color , float x , float y , int width , int flags , char const * text ) {
2016-09-08 00:32:21 +02:00
char stext [ 1024 ] ; // Copy of the passed text.
char * pch ; // A pointer to each word.
char word [ 255 ] ; // A string containing the word (for convienence)
char * breakchar = " \n " ;
char lines [ 40 ] [ 1024 ] ; // A lovely array of strings to hold all the lines (40 max atm)
char temp [ 1024 ] ; // Holds the string data of the current line only.
int line = 0 ; // Counts which line we are currently using.
int height = al_get_font_line_height ( font ) + 1 ;
// Setup our strings
strcpy ( stext , text ) ;
strcpy ( temp , " " ) ;
for ( int i = 0 ; i < 40 ; i + = 1 ) {
strcpy ( lines [ i ] , " " ) ;
}
//-------------------- Code Begins
char * context ;
pch = strtok_r ( stext , " " , & context ) ; // Get the first word.
do {
strcpy ( word , " " ) ; // Truncate the string, to ensure there's no crazy stuff in there from memory.
sprintf ( word , " %s " , pch ) ;
strcat ( temp , word ) ; // Append the word to the end of TempLine
// This code checks for the new line character.
if ( strcmp ( word , breakchar ) = = 0 ) {
line + = 1 ; // Move down a Line
strcpy ( temp , " " ) ; // Clear the tempstring
} else {
if ( al_get_text_width ( font , temp ) > = ( width ) ) { // Check if text is larger than the area.
strcpy ( temp , word ) ; // clear the templine and add the word to it.
line + = 1 ; // Move to the next line.
}
if ( line < 40 ) {
strcat ( lines [ line ] , word ) ; // Append the word to whatever line we are currently on.
}
}
pch = strtok_r ( NULL , " " , & context ) ; // Get the next word.
} while ( pch ! = NULL ) ;
// ---------------------------------- Time to draw.
for ( int i = 0 ; i < = line ; i + = 1 ) { // Move through each line and draw according to the passed flags.
switch ( flags ) {
case ALLEGRO_ALIGN_CENTER :
2016-09-08 01:42:48 +02:00
al_draw_text ( font , color , x + ( width / 2 ) , y + ( i * height ) , ALLEGRO_ALIGN_CENTER , lines [ i ] ) ;
2016-09-08 00:32:21 +02:00
break ;
case ALLEGRO_ALIGN_RIGHT :
2016-09-08 01:42:48 +02:00
al_draw_text ( font , color , x + width , y + ( i * height ) , ALLEGRO_ALIGN_RIGHT , lines [ i ] ) ;
2016-09-08 00:32:21 +02:00
break ;
case ALLEGRO_ALIGN_LEFT :
default :
2016-09-08 01:42:48 +02:00
al_draw_text ( font , color , x , y + ( i * height ) , ALLEGRO_ALIGN_LEFT , lines [ i ] ) ;
2016-09-08 00:32:21 +02:00
break ;
}
}
return ( ( line + 1 ) * height ) ; // Return the actual height of the text in pixels.
}
2016-09-08 01:42:48 +02:00
SYMBOL_EXPORT int DrawWrappedTextWithShadow ( ALLEGRO_FONT * font , ALLEGRO_COLOR color , float x , float y , int width , int flags , char const * text ) {
DrawWrappedText ( font , al_map_rgba ( 0 , 0 , 0 , 128 ) , x + 1 , y + 1 , width , flags , text ) ;
return DrawWrappedText ( font , color , x , y , width , flags , text ) ;
}
2016-09-08 00:32:21 +02:00
2016-06-27 21:20:02 +02:00
/* linear filtering code written by SiegeLord */
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT ALLEGRO_COLOR InterpolateColor ( ALLEGRO_COLOR c1 , ALLEGRO_COLOR c2 , float frac ) {
2016-06-27 21:20:02 +02:00
return al_map_rgba_f ( c1 . r + frac * ( c2 . r - c1 . r ) ,
2016-07-02 23:23:08 +02:00
c1 . g + frac * ( c2 . g - c1 . g ) ,
c1 . b + frac * ( c2 . b - c1 . b ) ,
c1 . a + frac * ( c2 . a - c1 . a ) ) ;
2012-12-24 19:41:12 +01:00
}
/*! \brief Scales bitmap using software linear filtering method to current target. */
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT void ScaleBitmap ( ALLEGRO_BITMAP * source , int width , int height ) {
2012-12-24 19:41:12 +01:00
if ( ( al_get_bitmap_width ( source ) = = width ) & & ( al_get_bitmap_height ( source ) = = height ) ) {
al_draw_bitmap ( source , 0 , 0 , 0 ) ;
return ;
}
int x , y ;
al_lock_bitmap ( al_get_target_bitmap ( ) , ALLEGRO_PIXEL_FORMAT_ANY , ALLEGRO_LOCK_WRITEONLY ) ;
al_lock_bitmap ( source , ALLEGRO_PIXEL_FORMAT_ANY , ALLEGRO_LOCK_READONLY ) ;
for ( y = 0 ; y < height ; y + + ) {
float pixy = ( ( float ) y / height ) * ( ( float ) al_get_bitmap_height ( source ) - 1 ) ;
float pixy_f = floor ( pixy ) ;
for ( x = 0 ; x < width ; x + + ) {
float pixx = ( ( float ) x / width ) * ( ( float ) al_get_bitmap_width ( source ) - 1 ) ;
float pixx_f = floor ( pixx ) ;
ALLEGRO_COLOR a = al_get_pixel ( source , pixx_f , pixy_f ) ;
ALLEGRO_COLOR b = al_get_pixel ( source , pixx_f + 1 , pixy_f ) ;
ALLEGRO_COLOR c = al_get_pixel ( source , pixx_f , pixy_f + 1 ) ;
ALLEGRO_COLOR d = al_get_pixel ( source , pixx_f + 1 , pixy_f + 1 ) ;
2016-07-04 00:06:50 +02:00
ALLEGRO_COLOR ab = InterpolateColor ( a , b , pixx - pixx_f ) ;
ALLEGRO_COLOR cd = InterpolateColor ( c , d , pixx - pixx_f ) ;
ALLEGRO_COLOR result = InterpolateColor ( ab , cd , pixy - pixy_f ) ;
2012-12-24 19:41:12 +01:00
al_put_pixel ( x , y , result ) ;
}
}
al_unlock_bitmap ( al_get_target_bitmap ( ) ) ;
al_unlock_bitmap ( source ) ;
}
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT ALLEGRO_BITMAP * LoadScaledBitmap ( struct Game * game , char * filename , int width , int height ) {
2012-12-24 19:41:12 +01:00
bool memoryscale = ! atoi ( GetConfigOptionDefault ( game , " SuperDerpy " , " GPU_scaling " , " 1 " ) ) ;
ALLEGRO_BITMAP * source , * target = al_create_bitmap ( width , height ) ;
al_set_target_bitmap ( target ) ;
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
2012-12-28 02:55:52 +01:00
char * origfn = GetDataFilePath ( game , filename ) ;
2012-12-24 19:41:12 +01:00
2016-11-11 19:38:26 +01:00
int flags = al_get_new_bitmap_flags ( ) ;
if ( memoryscale ) {
al_add_new_bitmap_flag ( ALLEGRO_MEMORY_BITMAP ) ;
}
2016-06-27 21:20:02 +02:00
source = al_load_bitmap ( origfn ) ;
if ( memoryscale ) {
2016-11-11 19:38:26 +01:00
al_set_new_bitmap_flags ( flags ) ;
2016-06-27 21:20:02 +02:00
ScaleBitmap ( source , width , height ) ;
2012-12-24 19:41:12 +01:00
}
2016-06-27 21:20:02 +02:00
else {
al_draw_scaled_bitmap ( source , 0 , 0 , al_get_bitmap_width ( source ) , al_get_bitmap_height ( source ) , 0 , 0 , width , height , 0 ) ;
}
al_destroy_bitmap ( source ) ;
2012-12-24 19:41:12 +01:00
free ( origfn ) ;
return target ;
2016-06-27 21:20:02 +02:00
2012-12-24 19:41:12 +01:00
}
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT void FatalError ( struct Game * game , bool fatal , char * format , . . . ) {
2012-12-28 02:55:52 +01:00
char text [ 1024 ] = { } ;
if ( ! game - > _priv . console ) {
va_list vl ;
va_start ( vl , format ) ;
2013-02-25 01:39:41 +01:00
vsnprintf ( text , 1024 , format , vl ) ;
2012-12-28 02:55:52 +01:00
va_end ( vl ) ;
printf ( " %s \n " , text ) ;
} else {
2013-06-03 00:42:33 +02:00
PrintConsole ( game , " Fatal Error, displaying Blue Screen of Derp... " ) ;
2012-12-28 02:55:52 +01:00
va_list vl ;
va_start ( vl , format ) ;
2013-02-25 01:39:41 +01:00
vsnprintf ( text , 1024 , format , vl ) ;
2012-12-28 02:55:52 +01:00
va_end ( vl ) ;
PrintConsole ( game , text ) ;
}
2016-06-27 21:20:02 +02:00
ALLEGRO_TRANSFORM trans ;
al_identity_transform ( & trans ) ;
al_use_transform ( & trans ) ;
2015-03-15 05:38:15 +01:00
if ( ! game - > _priv . font_bsod ) {
game - > _priv . font_bsod = al_create_builtin_font ( ) ;
}
2012-12-28 03:08:36 +01:00
al_set_target_backbuffer ( game - > display ) ;
al_clear_to_color ( al_map_rgb ( 0 , 0 , 170 ) ) ;
al_flip_display ( ) ;
2016-06-27 21:20:02 +02:00
al_rest ( 0.6 ) ;
2012-12-28 03:08:36 +01:00
2012-12-28 02:55:52 +01:00
bool done = false ;
while ( ! done ) {
al_set_target_backbuffer ( game - > display ) ;
al_clear_to_color ( al_map_rgb ( 0 , 0 , 170 ) ) ;
2016-07-03 22:38:36 +02:00
const char * header = game - > name ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_filled_rectangle ( al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header ) / 2 - 4 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 ) , 4 + al_get_display_width ( game - > display ) / 2 + al_get_text_width ( game - > _priv . font_bsod , header ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 ) + al_get_font_line_height ( game - > _priv . font_bsod ) , al_map_rgb ( 170 , 170 , 170 ) ) ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 0 , 0 , 170 ) , al_get_display_width ( game - > display ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 ) , ALLEGRO_ALIGN_CENTRE , header ) ;
2012-12-28 02:55:52 +01:00
2016-07-03 22:38:36 +02:00
const char * header2 = " A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) + " ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 2 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_CENTRE , header2 ) ;
al_draw_textf ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header2 ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 3 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_LEFT , " %p and system just doesn't know what went wrong. " , game ) ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 5 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_CENTRE , text ) ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header2 ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 7 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_LEFT , " * Press any key to terminate this error. " ) ;
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header2 ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 8 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_LEFT , " * Press any key to destroy all muffins in the world. " ) ;
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header2 ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 9 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_LEFT , " * Just kidding, please press any key anyway. " ) ;
2012-12-28 02:55:52 +01:00
if ( fatal ) {
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header2 ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 11 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_LEFT , " This is fatal error. My bad. " ) ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 13 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_CENTRE , " Press any key to quit _ " ) ;
2012-12-28 02:55:52 +01:00
} else {
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 - al_get_text_width ( game - > _priv . font_bsod , header2 ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 11 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_LEFT , " Anything I can do to help? " ) ;
2012-12-28 02:55:52 +01:00
2016-06-27 21:20:02 +02:00
al_draw_text ( game - > _priv . font_bsod , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) / 2 , ( int ) ( al_get_display_height ( game - > display ) * 0.32 + 13 * al_get_font_line_height ( game - > _priv . font_bsod ) * 1.25 ) , ALLEGRO_ALIGN_CENTRE , " Press any key to continue _ " ) ;
2012-12-28 02:55:52 +01:00
}
al_flip_display ( ) ;
2012-12-28 03:08:36 +01:00
ALLEGRO_KEYBOARD_STATE kb ;
al_get_keyboard_state ( & kb ) ;
int i ;
2016-06-27 21:20:36 +02:00
for ( i = 0 ; i < ALLEGRO_KEY_PAUSE ; i + + ) {
2012-12-28 03:08:36 +01:00
if ( al_key_down ( & kb , i ) ) {
done = true ;
break ;
}
}
2012-12-28 02:55:52 +01:00
}
2016-06-27 21:20:02 +02:00
al_use_transform ( & game - > projection ) ;
}
2016-07-04 01:12:55 +02:00
SYMBOL_INTERNAL void TestPath ( char * filename , char * subpath , char * * result ) {
2016-06-27 21:20:02 +02:00
if ( * result ) return ; //already found
ALLEGRO_PATH * tail = al_create_path ( filename ) ;
ALLEGRO_PATH * path = al_get_standard_path ( ALLEGRO_RESOURCES_PATH ) ;
ALLEGRO_PATH * data = al_create_path ( subpath ) ;
al_join_paths ( path , data ) ;
al_join_paths ( path , tail ) ;
//printf("Testing for %s\n", al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
if ( al_filename_exists ( al_path_cstr ( path , ALLEGRO_NATIVE_PATH_SEP ) ) ) {
* result = strdup ( al_path_cstr ( path , ALLEGRO_NATIVE_PATH_SEP ) ) ;
}
al_destroy_path ( tail ) ;
al_destroy_path ( data ) ;
al_destroy_path ( path ) ;
2012-12-28 02:55:52 +01:00
}
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT char * GetGameName ( struct Game * game , char * format ) {
2016-07-03 22:38:36 +02:00
char * result = malloc ( sizeof ( char ) * 255 ) ;
snprintf ( result , 255 , format , game - > name ) ;
2016-08-15 04:37:27 +02:00
return AddGarbage ( game , result ) ;
2016-07-03 22:38:36 +02:00
}
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT char * GetDataFilePath ( struct Game * game , char * filename ) {
2012-12-24 19:41:12 +01:00
char * result = 0 ;
if ( al_filename_exists ( filename ) ) {
2016-08-15 04:37:27 +02:00
return AddGarbage ( game , strdup ( filename ) ) ;
2012-12-24 19:41:12 +01:00
}
2016-06-28 00:17:49 +02:00
{
char origfn [ 255 ] = " data/ " ;
strcat ( origfn , filename ) ;
2012-12-24 19:41:12 +01:00
2016-06-28 00:17:49 +02:00
if ( al_filename_exists ( origfn ) ) {
2016-08-15 04:37:27 +02:00
return AddGarbage ( game , strdup ( origfn ) ) ;
2016-06-28 00:17:49 +02:00
}
2012-12-24 19:41:12 +01:00
}
2016-06-27 21:20:02 +02:00
TestPath ( filename , " data/ " , & result ) ;
2016-07-03 22:38:36 +02:00
TestPath ( filename , GetGameName ( game , " ../share/%s/data/ " ) , & result ) ;
2016-06-28 00:17:49 +02:00
2016-06-27 21:20:02 +02:00
TestPath ( filename , " ../data/ " , & result ) ;
# ifdef ALLEGRO_MACOSX
TestPath ( filename , " ../Resources/data/ " , & result ) ;
TestPath ( filename , " ../Resources/gamestates/ " , & result ) ;
# endif
2012-12-24 19:41:12 +01:00
if ( ! result ) {
2012-12-28 02:55:52 +01:00
FatalError ( game , true , " Could not find data file: %s! " , filename ) ;
2012-12-24 19:41:12 +01:00
exit ( 1 ) ;
}
2016-08-15 04:37:27 +02:00
return AddGarbage ( game , result ) ;
2012-12-24 19:41:12 +01:00
}
2016-11-08 17:42:23 +01:00
ALLEGRO_DEBUG_CHANNEL ( " libsuperderpy " )
2016-07-04 01:12:55 +02:00
SYMBOL_EXPORT void PrintConsole ( struct Game * game , char * format , . . . ) {
2012-12-24 19:41:12 +01:00
va_list vl ;
va_start ( vl , format ) ;
2012-12-26 02:25:56 +01:00
char text [ 1024 ] = { } ;
2013-02-25 01:39:41 +01:00
vsnprintf ( text , 1024 , format , vl ) ;
2012-12-24 19:41:12 +01:00
va_end ( vl ) ;
2016-11-08 17:56:19 +01:00
ALLEGRO_DEBUG ( " %s " , text ) ;
2012-12-24 19:41:12 +01:00
if ( game - > config . debug ) { printf ( " %s \n " , text ) ; fflush ( stdout ) ; }
2016-11-08 10:34:32 +01:00
if ( ! game - > _priv . draw ) return ;
2016-06-27 21:20:02 +02:00
if ( ! game - > _priv . console ) return ;
if ( ( ! game - > config . debug ) & & ( ! game - > _priv . showconsole ) ) return ;
2016-08-16 23:20:00 +02:00
al_set_target_bitmap ( game - > _priv . console_tmp ) ;
2012-12-24 19:41:12 +01:00
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 80 ) ) ;
2012-12-28 02:55:52 +01:00
al_draw_bitmap_region ( game - > _priv . console , 0 , ( int ) ( al_get_bitmap_height ( game - > _priv . console ) * 0.2 ) , al_get_bitmap_width ( game - > _priv . console ) , ( int ) ( al_get_bitmap_height ( game - > _priv . console ) * 0.8 ) , 0 , 0 , 0 ) ;
al_draw_text ( game - > _priv . font_console , al_map_rgb ( 255 , 255 , 255 ) , ( int ) ( game - > viewport . width * 0.005 ) , ( int ) ( al_get_bitmap_height ( game - > _priv . console ) * 0.81 ) , ALLEGRO_ALIGN_LEFT , text ) ;
2012-12-24 19:41:12 +01:00
al_set_target_bitmap ( game - > _priv . console ) ;
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
2016-08-16 23:20:00 +02:00
al_draw_bitmap ( game - > _priv . console_tmp , 0 , 0 , 0 ) ;
2012-12-24 19:41:12 +01:00
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
}
2016-08-15 04:41:54 +02:00
2016-09-08 00:32:21 +02:00
SYMBOL_EXPORT void SetupViewport ( struct Game * game , struct Viewport config ) {
2016-08-23 02:13:15 +02:00
game - > viewport = config ;
if ( ( game - > viewport . width = = 0 ) | | ( game - > viewport . height = = 0 ) ) {
game - > viewport . height = al_get_display_height ( game - > display ) ;
game - > viewport . width = game - > viewport . aspect * game - > viewport . height ;
if ( game - > viewport . width > al_get_display_width ( game - > display ) ) {
game - > viewport . width = al_get_display_width ( game - > display ) ;
2016-10-21 12:49:24 +02:00
game - > viewport . height = game - > viewport . width / ( float ) game - > viewport . aspect ;
2016-08-23 02:13:15 +02:00
}
}
2016-11-08 23:28:28 +01:00
game - > viewport . aspect = game - > viewport . width / ( float ) game - > viewport . height ;
2016-08-15 04:41:54 +02:00
2016-09-02 00:07:43 +02:00
al_set_target_backbuffer ( game - > display ) ;
al_identity_transform ( & game - > projection ) ;
al_use_transform ( & game - > projection ) ;
al_set_clipping_rectangle ( 0 , 0 , al_get_display_width ( game - > display ) , al_get_display_height ( game - > display ) ) ;
2016-11-08 23:28:28 +01:00
float resolution = al_get_display_height ( game - > display ) / ( float ) game - > viewport . height ;
if ( al_get_display_width ( game - > display ) / ( float ) game - > viewport . width < resolution ) {
resolution = al_get_display_width ( game - > display ) / ( float ) game - > viewport . width ;
}
2016-09-02 00:07:43 +02:00
if ( game - > viewport . integer_scaling ) {
2016-08-23 02:13:15 +02:00
resolution = floor ( resolution ) ;
}
2016-11-08 23:28:28 +01:00
if ( ( ! atoi ( GetConfigOptionDefault ( game , " SuperDerpy " , " downscale " , " 1 " ) ) ) & & ( resolution < 1 ) ) {
resolution = 1 ;
}
if ( ! atoi ( GetConfigOptionDefault ( game , " SuperDerpy " , " scaling " , " 1 " ) ) ) {
resolution = 1 ;
}
if ( resolution = = 0 ) {
resolution = 1 ;
}
2016-08-15 04:41:54 +02:00
2016-11-08 23:28:28 +01:00
int clipWidth = game - > viewport . width * resolution ;
int clipHeight = game - > viewport . height * resolution ;
2016-08-15 04:41:54 +02:00
if ( atoi ( GetConfigOptionDefault ( game , " SuperDerpy " , " letterbox " , " 1 " ) ) ) {
2016-11-08 23:28:28 +01:00
int clipX = ( al_get_display_width ( game - > display ) - clipWidth ) / 2 ;
int clipY = ( al_get_display_height ( game - > display ) - clipHeight ) / 2 ;
2016-08-15 04:41:54 +02:00
al_build_transform ( & game - > projection , clipX , clipY , resolution , resolution , 0.0f ) ;
2016-11-08 23:28:28 +01:00
al_set_clipping_rectangle ( clipX , clipY , clipWidth , clipHeight ) ;
} else if ( atoi ( GetConfigOptionDefault ( game , " SuperDerpy " , " scaling " , " 1 " ) ) ) {
al_build_transform ( & game - > projection , 0 , 0 , al_get_display_width ( game - > display ) / ( float ) game - > viewport . width , al_get_display_height ( game - > display ) / ( float ) game - > viewport . height , 0.0f ) ;
2016-08-15 04:41:54 +02:00
}
2016-11-08 23:28:28 +01:00
al_use_transform ( & game - > projection ) ;
2016-08-15 04:41:54 +02:00
if ( game - > _priv . console ) Console_Unload ( game ) ;
Console_Load ( game ) ;
}
2016-11-08 23:28:28 +01:00
SYMBOL_EXPORT void WindowCoordsToViewport ( struct Game * game , int * x , int * y ) {
int clipX , clipY , clipWidth , clipHeight ;
al_get_clipping_rectangle ( & clipX , & clipY , & clipWidth , & clipHeight ) ;
* x - = clipX ;
* y - = clipY ;
* x / = clipWidth / ( float ) game - > viewport . width ;
* y / = clipHeight / ( float ) game - > viewport . height ;
}
2017-05-07 01:30:22 +02:00
SYMBOL_EXPORT ALLEGRO_BITMAP * CreateNotPreservedBitmap ( int width , int height ) {
int flags = al_get_new_bitmap_flags ( ) ;
al_add_new_bitmap_flag ( ALLEGRO_NO_PRESERVE_TEXTURE ) ;
ALLEGRO_BITMAP * bitmap = al_create_bitmap ( width , height ) ;
al_set_new_bitmap_flags ( flags ) ;
return bitmap ;
}