From 2af8c7399c5647ab1f69db5e13e860ed97cf17d5 Mon Sep 17 00:00:00 2001 From: Galleon Date: Tue, 6 Jan 2015 03:55:55 -0800 Subject: [PATCH] Implements -g switch to compile with no graphical dependencies (Can now generate stand-alone executables <1MB) -g can be specified within code with: $CONSOLE:ONLY Note: Programs using this still need to call _DEST _CONSOLE or output will not be visible Also added dependency rules to remove unrequired static system libs from being linked: [X] lws2_32 as DEPENDENCY_SOCKETS _OPENHOST _OPENCLIENT [X] -lwinspool as DEPENDENCY_PRINTER LPRINT _PRINTIMAGE [X] -lwinmm & mmsystem.h Required by: FreeGlut (GUI) Audio Out [X] -lksguid (From the DirectX SDK, Required for Audio) Required by: Audio Out [X] -ldxguid (From the DirectX SDK, Required for Audio) Required by: Audio Out [X] -lole32 Required by: Audio Out (dsound.c) [X] -lgdi32 Required by: void sub__icon(int32 handle_icon, int32 handle_window_icon, int32 passed){ int32 func__screenimage(int32 x1,int32 y1,int32 x2,int32 y2,int32 passed) Printer Some code has been moved from inside libqb.cpp into subfolder internal\c\libqb Added dummy config.h file so libsamplerate could compile in Linux (Need to establish when it was removed) --- internal/c/common.cpp | 48 +- internal/c/libqb.cpp | 2662 +---------------- internal/c/libqb/gui.cpp | 2179 ++++++++++++++ internal/c/libqb/gui.h | 278 ++ internal/c/libqb/printer.cpp | 80 + internal/c/libqb/printer.h | 2 + .../c/parts/audio/libresample/src/config.h | 7 + internal/c/qbx.cpp | 460 +-- source/qb64.bas | 122 +- source/subs_functions/subs_functions.bas | 14 +- 10 files changed, 2826 insertions(+), 3026 deletions(-) create mode 100644 internal/c/libqb/gui.cpp create mode 100644 internal/c/libqb/gui.h create mode 100644 internal/c/libqb/printer.cpp create mode 100644 internal/c/libqb/printer.h create mode 100644 internal/c/parts/audio/libresample/src/config.h diff --git a/internal/c/common.cpp b/internal/c/common.cpp index 118ef2366..9d17274d4 100644 --- a/internal/c/common.cpp +++ b/internal/c/common.cpp @@ -1,3 +1,19 @@ +#ifndef DEPENDENCY_NO_SOCKETS + #define DEPENDENCY_SOCKETS +#endif + +#ifndef DEPENDENCY_NO_PRINTER + #define DEPENDENCY_PRINTER +#endif + +#ifndef DEPENDENCY_NO_ICON + #define DEPENDENCY_ICON +#endif + +#ifndef DEPENDENCY_NO_SCREENIMAGE + #define DEPENDENCY_SCREENIMAGE +#endif + #ifndef INC_COMMON_CPP #define INC_COMMON_CPP #include "os.h" @@ -19,7 +35,11 @@ #endif #endif - +#ifdef DEPENDENCY_CONSOLE_ONLY + #undef QB64_GLUT +#else + #define QB64_GUI +#endif #define NO_S_D_L @@ -34,6 +54,7 @@ //core +#ifdef QB64_GUI #ifdef QB64_GLUT #ifdef QB64_BACKSLASH_FILESYSTEM #include "parts\\core\\src.c" @@ -41,10 +62,19 @@ #include "parts/core/src.c" #endif #endif +#endif #ifdef QB64_WINDOWS -#include + +#ifndef QB64_GUI + #undef int64 //definition of int64 from os.h conflicts with a definition within windows.h, temporarily undefine then redefine + #include + #define int64 __int64 +#endif + #include +#include + #endif //common includes @@ -57,15 +87,18 @@ #include #include + //OS/compiler specific includes #ifdef QB64_WINDOWS #include -#include +#ifdef DEPENDENCY_PRINTER + #include +#endif #include #include //required for multi-threading - -//2013 midi -#include +#if defined DEPENDENCY_AUDIO_OUT || defined QB64_GUI + #include +#endif #else #include @@ -79,7 +112,7 @@ #endif #endif - +#ifdef QB64_GUI #ifdef QB64_GLUT #ifndef QB64_ANDROID #ifdef QB64_BACKSLASH_FILESYSTEM @@ -89,6 +122,7 @@ #endif #endif #endif +#endif using namespace std; diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index b2cc601b9..bede42a41 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -1,7 +1,9 @@ #include "common.cpp" #include "libqb.h" +#ifdef QB64_GUI #include "parts/core/glew/src/glew.c" +#endif #ifdef QB64_ANDROID #include //required for system() @@ -21,36 +23,14 @@ #include #endif +#include "libqb/printer.h" + void alert(int32 x); void alert(char *x); -int32 framebufferobjects_supported=0; - +//GUI notification variables int32 force_display_update=0; -int32 environment_2d__screen_width=0; //the size of the software SCREEN -int32 environment_2d__screen_height=0; -int32 environment__window_width=0; //window may be larger or smaller than the SCREEN -int32 environment__window_height=0; -int32 environment_2d__screen_x1=0; //offsets of 'screen' within the window -int32 environment_2d__screen_y1=0; -int32 environment_2d__screen_x2=0; -int32 environment_2d__screen_y2=0; -int32 environment_2d__screen_scaled_width=0; -int32 environment_2d__screen_scaled_height=0; -float environment_2d__screen_x_scale=1.0f; -float environment_2d__screen_y_scale=1.0f; -int32 environment_2d__screen_smooth=0;//1(LINEAR) or 0(NEAREST) -int32 environment_2d__letterbox=0;//1=vertical black stripes required, 2=horizontal black stripes required - - - -//forward ref(s) -void set_view(int32 new_mode); -void set_render_source(int32 new_handle); -void set_render_dest(int32 new_handle); -void reinit_glut_callbacks(); - void sub__delay(double seconds); void *generic_window_handle=NULL; @@ -69,6 +49,32 @@ extern "C" void QB64_Window_Handle(void *handle){ +//forward references +void set_view(int32 new_mode); +void set_render_source(int32 new_handle); +void set_render_dest(int32 new_handle); +void reinit_glut_callbacks(); + +int32 framebufferobjects_supported=0; + +int32 environment_2d__screen_width=0; //the size of the software SCREEN +int32 environment_2d__screen_height=0; +int32 environment__window_width=0; //window may be larger or smaller than the SCREEN +int32 environment__window_height=0; +int32 environment_2d__screen_x1=0; //offsets of 'screen' within the window +int32 environment_2d__screen_y1=0; +int32 environment_2d__screen_x2=0; +int32 environment_2d__screen_y2=0; +int32 environment_2d__screen_scaled_width=0; +int32 environment_2d__screen_scaled_height=0; +float environment_2d__screen_x_scale=1.0f; +float environment_2d__screen_y_scale=1.0f; +int32 environment_2d__screen_smooth=0;//1(LINEAR) or 0(NEAREST) +int32 environment_2d__letterbox=0;//1=vertical black stripes required, 2=horizontal black stripes required + + + + int32 qloud_next_input_index=1; int32 window_exists=0; @@ -519,235 +525,19 @@ list *hardware_graphics_command_handles=NULL; #define HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE3D 5 #define HARDWARE_GRAPHICS_COMMAND__CLEAR_DEPTHBUFFER 6 -int32 force_NPO2_fix=0;//This should only be set to 1 for debugging QB64 - -uint32 *NPO2_buffer=(uint32*)malloc(4); -int32 NPO2_buffer_size_in_pixels=1; - -uint32 *NPO2_texture_generate(int32 *px, int32 *py, uint32 *pixels){ -int32 ox=*px; -int32 oy=*py; -int32 nx=1; -int32 ny=1; - -//assume not negative & not 0 -while ((ox&1)==0){ - ox>>=1; - nx<<=1; -} -if (ox!=1){//x is not a power of 2 - while (ox!=0){ - ox>>=1; - nx<<=1; - } - nx<<1; -} -while ((oy&1)==0){ - oy>>=1; - ny<<=1; -} -if (oy!=1){//y is not a power of 2 - while (oy!=0){ - oy>>=1; - ny<<=1; - } - ny<<1; -} - -//reset original values -ox=*px; -oy=*py; - -if (nx==ox&&ny==oy){ //no action required - return pixels; -} - -int32 size_in_pixels=nx*ny; -if (size_in_pixels>NPO2_buffer_size_in_pixels){ - NPO2_buffer=(uint32*)realloc(NPO2_buffer,size_in_pixels*4); - NPO2_buffer_size_in_pixels=size_in_pixels; -} - -//copy source NPO2 rectangle into destination PO2 rectangle -if (nx==ox){ //can copy as a single block - memcpy(NPO2_buffer,pixels,ox*oy*4); -}else{ - uint32 *dst_pixel_offset=NPO2_buffer; - uint32 *src_pixel_offset=pixels; - while (oy--){ - memcpy(dst_pixel_offset,src_pixel_offset,ox*4); - dst_pixel_offset+=nx; - src_pixel_offset+=ox; - } - oy=*py; -} - -//tidy edges - extend the right-most column and bottom-most row to avoid pixel/color bleeding -//rhs column -if (ox!=nx){ -for (int y=0;yw=x; - hardware_img->h=y; - hardware_img->dest_context_handle=0; - hardware_img->depthbuffer_handle=0; - hardware_img->pending_commands=0; - hardware_img->remove=0; - hardware_img->alpha_disabled=0; - hardware_img->depthbuffer_mode=DEPTHBUFFER_MODE__ON; - hardware_img->valid=1; - hardware_img->source_state.PO2_fix=PO2_FIX__OFF; - hardware_img->source_state.texture_wrap=TEXTURE_WRAP_MODE__UNKNOWN; - hardware_img->source_state.smooth_stretched=SMOOTH_MODE__UNKNOWN; - hardware_img->source_state.smooth_shrunk=SMOOTH_MODE__UNKNOWN; - if (flags&NEW_HARDWARE_IMG__BUFFER_CONTENT){ - hardware_img->texture_handle=0; - if (flags&NEW_HARDWARE_IMG__DUPLICATE_PROVIDED_BUFFER){ - hardware_img->software_pixel_buffer=(uint32*)malloc(x*y*4); - memcpy(hardware_img->software_pixel_buffer,pixels,x*y*4); - }else{ - hardware_img->software_pixel_buffer=pixels; - } - }else{ - hardware_img->software_pixel_buffer=NULL; - hardware_img->texture_handle=new_texture_handle(); - glBindTexture (GL_TEXTURE_2D, hardware_img->texture_handle); - //non-power of 2 dimensions fallback support - static int glerrorcode; - glerrorcode=glGetError();//clear any previous errors - if (force_NPO2_fix==0) glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); - glerrorcode=glGetError(); - if (glerrorcode!=0||force_NPO2_fix==1){ - int32 nx=x,ny=y; - uint32 *npixels=NPO2_texture_generate(&nx,&ny,pixels); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_BGRA, GL_UNSIGNED_BYTE,npixels); - hardware_img->source_state.PO2_fix=PO2_FIX__EXPANDED; - hardware_img->PO2_w=nx; - hardware_img->PO2_h=ny; - glerrorcode=glGetError(); - if (glerrorcode){ - gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, x, y, GL_BGRA, GL_UNSIGNED_BYTE, pixels ); - glerrorcode=glGetError(); - if (glerrorcode){ - alert("gluBuild2DMipmaps failed"); - alert(glerrorcode); - } - hardware_img->source_state.PO2_fix=PO2_FIX__MIPMAPPED; - hardware_img->PO2_w=x; - hardware_img->PO2_h=y; - } - } - set_render_source(INVALID_HARDWARE_HANDLE); - } - return handle; -} +#include "libqb/gui.h" -void hardware_img_buffer_to_texture(int32 handle){ - static hardware_img_struct* hardware_img; - hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle); - if (hardware_img->texture_handle==0){ - hardware_img->texture_handle=new_texture_handle(); - glBindTexture (GL_TEXTURE_2D, hardware_img->texture_handle); - //non-power of 2 dimensions fallback support - static int glerrorcode; - glerrorcode=glGetError();//clear any previous errors - if (force_NPO2_fix==0) glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, hardware_img->w, hardware_img->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, hardware_img->software_pixel_buffer); - glerrorcode=glGetError(); - if (glerrorcode!=0||force_NPO2_fix==1){ - hardware_img->source_state.PO2_fix=PO2_FIX__EXPANDED; - int32 x=hardware_img->w; - int32 y=hardware_img->h; - uint32 *pixels=NPO2_texture_generate(&x,&y,hardware_img->software_pixel_buffer); - hardware_img->PO2_w=x; - hardware_img->PO2_h=y; - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_BGRA, GL_UNSIGNED_BYTE,pixels); - glerrorcode=glGetError(); - if (glerrorcode){ - gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, hardware_img->w, hardware_img->h, GL_BGRA, GL_UNSIGNED_BYTE, hardware_img->software_pixel_buffer); - glerrorcode=glGetError(); - if (glerrorcode){ - alert("gluBuild2DMipmaps failed"); - alert(glerrorcode); - } - hardware_img->source_state.PO2_fix=PO2_FIX__MIPMAPPED; - hardware_img->PO2_w=hardware_img->w; - hardware_img->PO2_h=hardware_img->h; - } - } - free(hardware_img->software_pixel_buffer); - set_render_source(INVALID_HARDWARE_HANDLE); - } -} - -void hardware_img_requires_depthbuffer(hardware_img_struct* hardware_img){ -if (hardware_img->depthbuffer_handle==0){ - //inspiration... http://www.opengl.org/wiki/Framebuffer_Object_Examples#Color_texture.2C_Depth_texture - static GLuint depth_tex; - glGenTextures(1, &depth_tex); - glBindTexture(GL_TEXTURE_2D, depth_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - //NULL means reserve texture memory, but texels are undefined - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, hardware_img->w, hardware_img->h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0/*mipmap level*/); - glClear(GL_DEPTH_BUFFER_BIT); - hardware_img->depthbuffer_handle=depth_tex; - set_render_source(INVALID_HARDWARE_HANDLE); -} -} + //these lock values increment + int64 display_lock_request=0; + int64 display_lock_confirmed=0; + int64 display_lock_released=0; //note: only to be used by user functions, not internal functions hardware_img_struct *get_hardware_img(int32 handle){ @@ -1221,7 +1011,7 @@ int32 width_lprint=80; void sub_shell4(qbs*,int32);//_DONTWAIT & _HIDE int32 func__source(); int32 func_pos(int32 ignore); -void sub__printimage(int32 i); + double func_timer(double accuracy,int32 passed); int32 func__newimage(int32 x,int32 y,int32 bpp,int32 passed); void display(); @@ -19551,37 +19341,27 @@ void sub_mkdir(qbs *str){ } void sub__mousehide(){ - + #ifdef QB64_GUI if (!screen_hide){ - while (!window_exists){Sleep(100);} + while (!window_exists){Sleep(100);} + #ifdef QB64_GLUT glutSetCursor(GLUT_CURSOR_NONE); + #endif } - - -#ifndef NO_S_D_L - -#ifdef QB64_LINUX - lock_mainloop=1; while (lock_mainloop!=2) Sleep(1);//lock -#endif - mouse_hideshow_called=1; - static int x,y; - SDL_GetMouseState(&x,&y); - SDL_WarpMouse(x,y); - SDL_ShowCursor(0); - SDL_WarpMouse(x,y); -#ifdef QB64_LINUX - lock_mainloop=0; Sleep(1);//unlock -#endif - -#endif //NO_S_D_L - + #endif } +#ifdef QB64_GLUT int mouse_cursor_style=GLUT_CURSOR_LEFT_ARROW; +#else + int mouse_cursor_style=1; +#endif void sub__mouseshow(qbs *style, int32 passed){ if (new_error) return; +#ifdef QB64_GLUT + static qbs *str=NULL; if (str==NULL) str=qbs_new(0,0); if (passed){ qbs_set(str,qbs_ucase(style)); @@ -19602,25 +19382,7 @@ void sub_mkdir(qbs *str){ glutSetCursor(mouse_cursor_style); } - -#ifndef NO_S_D_L - - device_mouse_relative=0; -#ifdef QB64_LINUX - lock_mainloop=1; while (lock_mainloop!=2) Sleep(1);//lock #endif - mouse_hideshow_called=1; - static int x,y; - if (SDL_WM_GrabInput(SDL_GRAB_QUERY)==SDL_GRAB_ON) SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_GetMouseState(&x,&y); - SDL_WarpMouse(x,y); - SDL_ShowCursor(1); - SDL_WarpMouse(x,y); -#ifdef QB64_LINUX - lock_mainloop=0; Sleep(1);//unlock -#endif - -#endif //NO_S_D_L } @@ -21300,6 +21062,10 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ exit(0);//<-- should never happen } +#ifdef DEPENDENCY_CONSOLE_ONLY + screen_hide=1; +#endif + if (!screen_hide){ //1. set the display page as the destination page sub__dest(func__display()); @@ -22097,6 +21863,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ } +#ifdef DEPENDENCY_ICON void sub__icon(int32 handle_icon, int32 handle_window_icon, int32 passed){ if (new_error) return; @@ -22199,6 +21966,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ }//!screen_hide }//sub__icon +#endif //DEPENDENCY_ICON void sub__autodisplay(){ autodisplay=1; @@ -22753,7 +22521,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ static int32 init=0; if (!init){ init=1; -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) sockVersion = MAKEWORD(1, 1); WSAStartup(sockVersion, &wsaData); #endif @@ -22761,13 +22529,13 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ } void tcp_done(){ -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) WSACleanup(); #endif } struct tcp_connection{ -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) SOCKET socket; #endif int32 port;//connection to host & clients only @@ -22779,7 +22547,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ tcp_init(); if ((port<0)||(port>65535)) return NULL; -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) //Ref. from 'winsock.h': typedef u_int SOCKET; static SOCKET listeningSocket; listeningSocket = socket(AF_INET, // Go over TCP/IP @@ -22826,7 +22594,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ if ((port<0)||(port>65535)) return NULL; -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) static LPHOSTENT hostEntry; hostEntry=gethostbyname((char*)host); if (!hostEntry) return NULL; @@ -22870,7 +22638,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ void *tcp_connection_open(void *host_tcp){ -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) static tcp_connection *host; host=(tcp_connection*)host_tcp; static sockaddr sa; static int sa_size; @@ -22897,7 +22665,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ void tcp_close(void* connection){ static tcp_connection *tcp=(tcp_connection*)connection; -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) shutdown(tcp->socket,SD_BOTH); closesocket(tcp->socket); #endif @@ -22907,7 +22675,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ void tcp_out(void *connection,void *offset,ptrszint bytes){ -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) static tcp_connection *tcp; tcp=(tcp_connection*)connection; static int nret; nret = send(tcp->socket, @@ -22948,7 +22716,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ void stream_update(stream_struct *stream){ -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) //assume tcp static connection_struct *connection; @@ -23272,7 +23040,7 @@ int32 func__printwidth(qbs* text, int32 screenhandle, int32 passed){ int32 tcp_connected (void *connection){ static tcp_connection *tcp=(tcp_connection*)connection; -#ifdef QB64_WINDOWS +#if defined(QB64_WINDOWS) && defined(QB64_SOCKETS) char buf; int length=recv(tcp->socket, &buf, 0, 0); int nError=WSAGetLastError(); @@ -24933,6 +24701,7 @@ int32 func__exit(){ } +#ifdef DEPENDENCY_SCREENIMAGE int32 func__screenimage(int32 x1,int32 y1,int32 x2,int32 y2,int32 passed){ if (cloud_app) return func__newimage(1024,768,32,1); @@ -25236,6 +25005,7 @@ int32 func__exit(){ return -1; } +#endif //DEPENDENCY_SCREENIMAGE void sub__screenclick(int32 x,int32 y){ @@ -26099,77 +25869,8 @@ int32 func__exit(){ } - void sub__printimage(int32 i){ -#ifdef QB64_WINDOWS - - static LPSTR szPrinterName=NULL; - DWORD dwNameLen; - HDC dc; - DOCINFO di; - uint32 w,h; - int32 x,y; - int32 i2; - BITMAPFILEHEADER bmfHeader; - BITMAPINFOHEADER bi; - img_struct *s,*s2; - - if (i>=0){ - validatepage(i); s=&img[page[i]]; - }else{ - x=-i; - if (x>=nextimg){error(258); return;} - s=&img[x]; - if (!s->valid){error(258); return;} - } - - if (!szPrinterName) szPrinterName=(LPSTR)malloc(65536); - dwNameLen=65536; - GetDefaultPrinter(szPrinterName,&dwNameLen); - if((dc=CreateDC(TEXT("WINSPOOL"),szPrinterName,NULL,NULL))==NULL) goto failed; - ZeroMemory(&di,sizeof(DOCINFO)); - di.cbSize=sizeof(DOCINFO); - di.lpszDocName=TEXT("Document"); - if(StartDoc(dc,&di)<=0){DeleteDC(dc); goto failed;} - if(StartPage(dc)<=0){EndDoc(dc); DeleteDC(dc); goto failed;} - - w=GetDeviceCaps(dc,HORZRES); - h=GetDeviceCaps(dc,VERTRES); - - i2=func__newimage(w,h,32,1); - if (i2==-1){EndDoc(dc); DeleteDC(dc); goto failed;} - s2=&img[-i2]; - sub__dontblend(i2,1); - sub__putimage(NULL,NULL,NULL,NULL,i,i2,NULL,NULL,NULL,NULL,8+32); - - ZeroMemory(&bi,sizeof(BITMAPINFOHEADER)); - - bi.biSize = sizeof(BITMAPINFOHEADER); - bi.biWidth = w; - bi.biHeight = h; - bi.biPlanes = 1; - bi.biBitCount = 32; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; - bi.biXPelsPerMeter = 0; - bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; - bi.biClrImportant = 0; - - for (y=0;yoffset32+(y*w),(BITMAPINFO*)&bi, DIB_RGB_COLORS); - } - - sub__freeimage(i2,1); - - if(EndPage(dc)<=0){EndDoc(dc); DeleteDC(dc); goto failed;} - if(EndDoc(dc)<=0){DeleteDC(dc); goto failed;} - DeleteDC(dc); - failed:; - -#endif - - } +#include "libqb/printer.cpp" void sub_files(qbs *str,int32 passed){ if (new_error) return; @@ -26184,6 +25885,8 @@ int32 func__exit(){ qbs_set(strz,qbs_new_txt_len("\0",1)); } + + #ifdef QB64_WINDOWS static WIN32_FIND_DATA fd; static HANDLE hFind; @@ -27052,19 +26755,27 @@ int32 func__exit(){ } int32 func__screenx(){ - #ifdef QB64_WINDOWS + #ifdef QB64_GUI + #ifdef QB64_WINDOWS + #ifdef QB64_GLUT while (!window_exists){Sleep(100);} //Wait for window to be created before checking position return glutGet(GLUT_WINDOW_X) - glutGet(GLUT_WINDOW_BORDER_WIDTH); - #endif - return 0; //if not windows then return 0 + #endif + #endif + #endif + return 0; //if not windows then return 0 } int32 func__screeny(){ - #ifdef QB64_WINDOWS - while (!window_exists){Sleep(100);} //Wait for window to be created before checking position - return glutGet(GLUT_WINDOW_Y) - glutGet(GLUT_WINDOW_BORDER_WIDTH) - glutGet(GLUT_WINDOW_HEADER_HEIGHT); - #endif - return 0; //if not windows then return 0 + #ifdef QB64_GUI + #ifdef QB64_WINDOWS + #ifdef QB64_GLUT + while (!window_exists){Sleep(100);} //Wait for window to be created before checking position + return glutGet(GLUT_WINDOW_Y) - glutGet(GLUT_WINDOW_BORDER_WIDTH) - glutGet(GLUT_WINDOW_HEADER_HEIGHT); + #endif + #endif + #endif + return 0; //if not windows then return 0 } void sub__screenmove(int32 x,int32 y,int32 passed){ @@ -27072,7 +26783,9 @@ int32 func__exit(){ if (!passed) goto error; if (passed==3) goto error; if (full_screen) return; - + + #ifdef QB64_GUI + #ifdef QB64_GLUT while (!window_exists){Sleep(100);} //wait for window to be created before moving it. if (passed==2){ glutPositionWindow (x,y);} @@ -27085,7 +26798,10 @@ int32 func__exit(){ x = (SW - WW)/2; y = (SH - WH)/2; glutPositionWindow (x,y); - } + } + #endif + #endif + return; error: @@ -28738,2176 +28454,7 @@ void sub__maptriangle(int32 cull_options,float sx1,float sy1,float sx2,float sy2 } #endif - - - void GLUT_RESHAPE_FUNC(int width, int height){ - resize_event_x=width; resize_event_y=height; - resize_event=-1; - display_x_prev=display_x,display_y_prev=display_y; - display_x=width; display_y=height; - resize_pending=0; - os_resize_event=1; - set_view(VIEW_MODE__UNKNOWN); - //***glutReshapeWindow(...) has no effect if called - // within GLUT_RESHAPE_FUNC*** - } - - - - - //displaycall is the window of time to update our display - - //these lock values increment - int64 display_lock_request=0; - int64 display_lock_confirmed=0; - int64 display_lock_released=0; - -#ifdef DEPENDENCY_GL - extern void SUB__GL(); -#endif - - int32 displayorder_screen=1; - int32 displayorder_hardware=2; - int32 displayorder_glrender=3; - int32 displayorder_hardware1=4; - - //sub__displayorder( 1 , 2 , 4 , 3 ); - //id.specialformat = "[{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}[,{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}[,{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}[,{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}]]]]" - void sub__displayorder(int32 method1,int32 method2,int32 method3,int32 method4){ - - //check no value has been used twice - if (method1!=0) if (method1==method2||method1==method3||method1==method4){error(5); return;} - if (method2!=0) if (method2==method1||method2==method3||method2==method4){error(5); return;} - if (method3!=0) if (method3==method1||method3==method2||method3==method4){error(5); return;} - if (method4!=0) if (method4==method1||method4==method2||method4==method3){error(5); return;} - displayorder_screen=0; - displayorder_hardware=0; - displayorder_hardware1=0; - displayorder_glrender=0; - static int32 i,method; - for (i=1;i<=4;i++){ - if (i==1) method=method1; - if (i==2) method=method2; - if (i==3) method=method3; - if (i==4) method=method4; - if (method==1) displayorder_screen=i; - if (method==2) displayorder_hardware=i; - if (method==3) displayorder_hardware1=i; - if (method==4) displayorder_glrender=i; - } - } - - //int32 gl_render_method=2; //1=behind, 2=ontop[default], 3=only - void sub__glrender(int32 method){ - //gl_render_method=method; - if (method==1) sub__displayorder(4,1,2,3); - if (method==2) sub__displayorder(1,2,4,3); - if (method==3) sub__displayorder(4,0,0,0); - } - - - - - - - - -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 - - - - /* reference - struct hardware_img_struct{ - int32 w; - int32 h; - int32 texture_handle; - int32 dest_context_handle;//used when rendering other images onto this image - int32 temp;//if =1, delete immediately after use - } - list *hardware_img_handles=NULL; - */ - - - - void free_hardware_img(int32 handle){ - - //alert("free_hardware_img: entered"); - - static hardware_img_struct* hardware_img; - hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle); - - if (hardware_img==NULL) alert("free_hardware_img: image does not exist"); - - if (hardware_img->dest_context_handle){ - GLuint context=(GLuint)hardware_img->dest_context_handle; - glDeleteFramebuffersEXT(1, &context); - } - if (hardware_img->depthbuffer_handle){ - GLuint depthbuffer_handle=(GLuint)hardware_img->depthbuffer_handle; - glDeleteFramebuffersEXT(1, &depthbuffer_handle); - } - GLuint texture=(GLuint)hardware_img->texture_handle; - glDeleteTextures(1, &texture); - - //if image has not been used, it may still have buffered pixel content - if (hardware_img->software_pixel_buffer!=NULL) free(hardware_img->software_pixel_buffer); - - list_remove(hardware_img_handles,handle); - } - - - /* - int32 new_hardware_frame(int32 x, int32 y){ - int32 handle=new_hardware_frame_handle(); - glBindTexture (GL_TEXTURE_2D, handle); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - return handle; - } - - void free_hardware_frame(int32 handle){ - GLuint texture=(GLuint)handle; - glDeleteTextures(1, &texture); - } - */ - - - - - void prepare_environment_2d(){//called prior to rendering 2D content - - //precalculate critical dimensions, offsets & ratios - - static int32 can_scale;//can the screen be scaled on the window - can_scale=0; - static int32 need_square_pixels;//do we need square_pixels? if not we can stretch the screen - need_square_pixels=0; - - environment_2d__screen_smooth=0; - - environment_2d__letterbox=0; - - if (full_screen>0){//in full screen - //reference: ---int32 full_screen_set=-1;//0(windowed),1(stretched/closest),2(1:1)--- - can_scale=1; - if (full_screen==2) need_square_pixels=1; - //note: 'letter-boxing' is only requred where the size of the window cannot be controlled, and the only place where this is the - // case is full screen mode _SQUAREPIXELS - environment_2d__screen_smooth=fullscreen_smooth; - }else{//windowed - if (resize_auto>0){//1=STRETCH,2=SMOOTH - can_scale=1; - if (resize_auto==2) environment_2d__screen_smooth=1; - //note: screen will fix its aspect ratio automatically, so there is no need to enforce squarepixels - } - } - - if (environment_2d__screen_width==environment__window_width && - environment_2d__screen_height==environment__window_height){ - //screen size matches window - environment_2d__screen_x1=0; - environment_2d__screen_y1=0; - environment_2d__screen_x2=environment_2d__screen_width-1; - environment_2d__screen_y2=environment_2d__screen_height-1; - environment_2d__screen_x_scale=1.0f; - environment_2d__screen_y_scale=1.0f; - environment_2d__screen_scaled_width=environment_2d__screen_width; - environment_2d__screen_scaled_height=environment_2d__screen_height; - environment_2d__screen_smooth=0;//no smoothing required - }else{ - //screen size does not match - //calculate ratios - static float window_ratio; - static float screen_ratio; - window_ratio=(float)environment__window_width/(float)environment__window_height; - screen_ratio=(float)environment_2d__screen_width/(float)environment_2d__screen_height; - if (can_scale==0){ - //screen will appear in the top-left of the window with blank space on the bottom & right - environment_2d__screen_x1=0; - environment_2d__screen_y1=0; - environment_2d__screen_x2=environment_2d__screen_width-1; - environment_2d__screen_y2=environment_2d__screen_height-1; - goto cant_scale; - } - if (need_square_pixels==0||(window_ratio==screen_ratio)){ - //can stretch, no 'letter-box' required - environment_2d__screen_x1=0; - environment_2d__screen_y1=0; - environment_2d__screen_x2=environment__window_width-1; - environment_2d__screen_y2=environment__window_height-1; - }else{ - //'letter-box' required - //this section needs revision - static float x_scale,y_scale; - static int32 x1,y1,x2,y2,z,x_limit,y_limit,x_offset,y_offset; - //x_scale=(float)environment_2d__screen_width/(float)environment__window_width; - //y_scale=(float)environment_2d__screen_height/(float)environment__window_height; - //x_offset=0; y_offset=0; - - x1=0; y1=0; x2=environment__window_width-1; y2=environment__window_height-1; - //x_limit=x2; y_limit=y2; - if (window_ratio>screen_ratio){ - //pad sides - z=(float)environment__window_height*screen_ratio;//new width - x1=environment__window_width/2-z/2; - x2=x1+z-1; - environment_2d__letterbox=1;//vertical black stripes required - //x_offset=-x1; x_scale=(float)environment_2d__screen_width/(float)z; x_limit=z-1; - }else{ - //pad top/bottom - z=(float)environment__window_width/screen_ratio;//new height - y1=environment__window_height/2-z/2; - y2=y1+z-1; - environment_2d__letterbox=2;//horizontal black stripes required - //y_offset=-y1; y_scale=(float)environment_2d__screen_height/(float)z; y_limit=z-1; - } - environment_2d__screen_x1=x1; - environment_2d__screen_y1=y1; - environment_2d__screen_x2=x2; - environment_2d__screen_y2=y2; - } - cant_scale: - environment_2d__screen_scaled_width=environment_2d__screen_x2-environment_2d__screen_x1+1; - environment_2d__screen_scaled_height=environment_2d__screen_y2-environment_2d__screen_y1+1; - environment_2d__screen_x_scale=(float)environment_2d__screen_scaled_width/(float)environment_2d__screen_width; - environment_2d__screen_y_scale=(float)environment_2d__screen_scaled_height/(float)environment_2d__screen_height; - } - - }//prepare_environment_2d - - - int32 environment_2d__get_window_x1_coord(int32 x){ - return qbr_float_to_long(((float)x)*environment_2d__screen_x_scale)+environment_2d__screen_x1; - } - int32 environment_2d__get_window_y1_coord(int32 y){ - return qbr_float_to_long((float)y*environment_2d__screen_y_scale)+environment_2d__screen_y1; - } - int32 environment_2d__get_window_x2_coord(int32 x){ - return qbr_float_to_long(((float)x+1.0f)*environment_2d__screen_x_scale-1.0f)+environment_2d__screen_x1; - } - - int32 environment_2d__get_window_y2_coord(int32 y){ - return qbr_float_to_long(((float)y+1.0f)*environment_2d__screen_y_scale-1.0f)+environment_2d__screen_y1; - } - - struct environment_2d__window_rect_struct{ - int32 x1; - int32 y1; - int32 x2; - int32 y2; - }; - - //this functions returns a constant rect dimensions to stop warping of image - environment_2d__window_rect_struct tmp_rect; - environment_2d__window_rect_struct *environment_2d__screen_to_window_rect(int32 x1,int32 y1,int32 x2,int32 y2){ - tmp_rect.x1=qbr_float_to_long(((float)x1)*environment_2d__screen_x_scale)+environment_2d__screen_x1; - tmp_rect.y1=qbr_float_to_long(((float)y1)*environment_2d__screen_y_scale)+environment_2d__screen_y1; - static int32 w,h; - w=abs(x2-x1)+1; h=abs(y2-y1)+1; - //force round upwards to correct gaps when tiling - w=((float)w)*environment_2d__screen_x_scale+0.99f; - h=((float)h)*environment_2d__screen_y_scale+0.99f; - tmp_rect.x2=w-1+tmp_rect.x1; - tmp_rect.y2=h-1+tmp_rect.y1; - //(code which doesn't support tiling) - //tmp_rect.x2=qbr_float_to_long(((float)w)*environment_2d__screen_x_scale-1.0f)+tmp_rect.x1; - //tmp_rect.y2=qbr_float_to_long(((float)h)*environment_2d__screen_y_scale-1.0f)+tmp_rect.y1; - return &tmp_rect; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -float *hardware_buffer_vertices=(float*)malloc(sizeof(float)*1); -int32 *hardware_buffer_vertices_int; - -int32 hardware_buffer_vertices_max=1; -int32 hardware_buffer_vertices_count=0; - -float *hardware_buffer_texcoords=(float*)malloc(sizeof(float)*1); -int32 hardware_buffer_texcoords_max=1; -int32 hardware_buffer_texcoords_count=0; - -void hardware_buffer_flush(){ - if (hardware_buffer_vertices_count){ - //ref: http://stackoverflow.com/questions/5009014/draw-square-with-opengl-es-for-ios - if (hardware_buffer_vertices_count==hardware_buffer_texcoords_count){ - glVertexPointer(2, GL_INT, 2*sizeof(GL_INT), (int32*)hardware_buffer_vertices); //http://www.opengl.org/sdk/docs/man2/xhtml/glVertexPointer.xml - glTexCoordPointer(2, GL_FLOAT, 2*sizeof(GL_FLOAT), hardware_buffer_texcoords); //http://www.opengl.org/sdk/docs/man2/xhtml/glTexCoordPointer.xml - glDrawArrays(GL_TRIANGLES, 0, hardware_buffer_vertices_count/2);//start index, number of indexes - }else{ - glVertexPointer(3, GL_FLOAT, 3*sizeof(GL_FLOAT), hardware_buffer_vertices); //http://www.opengl.org/sdk/docs/man2/xhtml/glVertexPointer.xml - glTexCoordPointer(2, GL_FLOAT, 2*sizeof(GL_FLOAT), hardware_buffer_texcoords); //http://www.opengl.org/sdk/docs/man2/xhtml/glTexCoordPointer.xml - glDrawArrays(GL_TRIANGLES, 0, hardware_buffer_vertices_count/3);//start index, number of indexes - } - hardware_buffer_vertices_count=0; - hardware_buffer_texcoords_count=0; - } -} - - - - -void set_smooth(int32 new_mode_shrunk,int32 new_mode_stretched){ -static int32 current_mode_shrunk; -current_mode_shrunk=render_state.source->smooth_shrunk; -static int32 current_mode_stretched; -current_mode_stretched=render_state.source->smooth_stretched; -if (new_mode_shrunk==current_mode_shrunk&&new_mode_stretched==current_mode_stretched) return; -hardware_buffer_flush(); -if (new_mode_shrunk==SMOOTH_MODE__DONT_SMOOTH){ - if (render_state.source->PO2_fix==PO2_FIX__MIPMAPPED){ - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - }else{ - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } -} -if (new_mode_shrunk==SMOOTH_MODE__SMOOTH){ - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -} -if (new_mode_stretched==SMOOTH_MODE__DONT_SMOOTH){ - if (render_state.source->PO2_fix==PO2_FIX__MIPMAPPED){ - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - }else{ - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } -} -if (new_mode_stretched==SMOOTH_MODE__SMOOTH){ - glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -} -render_state.source->smooth_shrunk=new_mode_shrunk; -render_state.source->smooth_stretched=new_mode_stretched; -} - -void set_texture_wrap(int32 new_mode){ -static int32 current_mode; -current_mode=render_state.source->texture_wrap; -if (new_mode==current_mode) return; -hardware_buffer_flush(); -if (new_mode==TEXTURE_WRAP_MODE__DONT_WRAP){ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -} -if (new_mode==TEXTURE_WRAP_MODE__WRAP){ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -} -render_state.source->texture_wrap=new_mode; -} - -void set_alpha(int32 new_mode){ -static int32 current_mode; -current_mode=render_state.use_alpha; -if (new_mode==current_mode) return; -hardware_buffer_flush(); -if (new_mode==ALPHA_MODE__DONT_BLEND){ - glDisable(GL_BLEND); -} -if (new_mode==ALPHA_MODE__BLEND){ - glEnable(GL_BLEND); - if (framebufferobjects_supported){ - //glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - }else{ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } -} -render_state.use_alpha=new_mode; -} - -void set_depthbuffer(int32 new_mode){ -static int32 current_mode; -current_mode=render_state.depthbuffer_mode; -if (new_mode==current_mode) return; -hardware_buffer_flush(); -if (new_mode==DEPTHBUFFER_MODE__OFF){ - glDisable(GL_DEPTH_TEST); - glAlphaFunc(GL_ALWAYS, 0); -} -if (new_mode==DEPTHBUFFER_MODE__ON){ - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glAlphaFunc(GL_GREATER, 0.001); - glEnable(GL_ALPHA_TEST); -} -if (new_mode==DEPTHBUFFER_MODE__LOCKED){ - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glAlphaFunc(GL_ALWAYS, 0); -} -render_state.depthbuffer_mode=new_mode; -} - -void set_cull_mode(int32 new_mode){ -static int32 current_mode; -current_mode=render_state.cull_mode; -if (new_mode==current_mode) return; -hardware_buffer_flush(); -if (new_mode==CULL_MODE__NONE){ - glDisable(GL_CULL_FACE); -} -if (new_mode==CULL_MODE__CLOCKWISE_ONLY){ - glFrontFace(GL_CW); - if (current_mode!=CULL_MODE__ANTICLOCKWISE_ONLY) glEnable(GL_CULL_FACE); -} -if (new_mode==CULL_MODE__ANTICLOCKWISE_ONLY){ - glFrontFace(GL_CCW); - if (current_mode!=CULL_MODE__CLOCKWISE_ONLY) glEnable(GL_CULL_FACE); -} -render_state.cull_mode=new_mode; -} - -void set_view(int32 new_mode){ //set view can only be called after the correct destination is chosen -static int32 current_mode; -current_mode=render_state.view_mode; -if (new_mode==current_mode) return; -hardware_buffer_flush(); -if (new_mode==VIEW_MODE__RESET){ - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glDisable(GL_LIGHTING); - glFrontFace(GL_CCW); - glCullFace(GL_BACK); - glDisable(GL_CULL_FACE); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glAlphaFunc(GL_ALWAYS, 0); - if (framebufferobjects_supported) glBindFramebufferEXT(GL_FRAMEBUFFER, 0); - glBindTexture (GL_TEXTURE_2D, 0); - glClear(GL_DEPTH_BUFFER_BIT); - glColor4f(1.f, 1.f, 1.f, 1.f); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - //invalidate current states - set_alpha(ALPHA_MODE__UNKNOWN); - set_depthbuffer(DEPTHBUFFER_MODE__UNKNOWN); - set_cull_mode(CULL_MODE__UNKNOWN); - set_render_source(INVALID_HARDWARE_HANDLE); - set_render_dest(INVALID_HARDWARE_HANDLE); - new_mode=VIEW_MODE__UNKNOWN;//resets are performed before unknown operations are executed -} -if (new_mode==VIEW_MODE__2D){ - if (current_mode!=VIEW_MODE__3D){ - glColor4f(1.f, 1.f, 1.f, 1.f); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - set_alpha(ALPHA_MODE__BLEND); - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glCullFace(GL_BACK); - } - - if (render_state.dest_handle==0){ - static int32 dst_w,dst_h; - dst_w=environment__window_width; - dst_h=environment__window_height; - -//alert(dst_w); -//alert(dst_h); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0, dst_w, 0.0, dst_h, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glScalef(1, -1, 1);//flip vertically - glTranslatef(0, -dst_h, 0);//move to new vertical position - glViewport(0,0,dst_w,dst_h); - }else{ - static hardware_img_struct* hardware_img; - hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,render_state.dest_handle); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0, hardware_img->w, 0, hardware_img->h); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glViewport(0,0,hardware_img->w,hardware_img->h); - } -} -if (new_mode==VIEW_MODE__3D){ - if (current_mode!=VIEW_MODE__2D){ - glColor4f(1.f, 1.f, 1.f, 1.f); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - set_alpha(ALPHA_MODE__BLEND); - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glCullFace(GL_BACK); - } - if (render_state.dest_handle==0){ - static int32 dst_w,dst_h; - dst_w=environment__window_width; - dst_h=environment__window_height; - glViewport(0, 0, (GLsizei)dst_w, (GLsizei)dst_h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - //note: the max FOV is 90-degrees (this maximum applies to the longest screen dimension) - float fov; - if (environment_2d__screen_scaled_width>environment_2d__screen_scaled_height){ - fov=90.0f*((float)environment__window_width/(float)environment_2d__screen_scaled_width); - //convert fov from horizontal to vertical - fov=fov*((float)dst_h/(float)dst_w); - }else{ - fov=90.0f*((float)environment__window_height/(float)environment_2d__screen_scaled_height); - } - gluPerspective(fov, (GLfloat)dst_w / (GLfloat)dst_h, 0.1, 10000.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - }else{ - - static hardware_img_struct* hardware_img; - hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,render_state.dest_handle); - - static int32 dst_w,dst_h; - dst_w=hardware_img->w; - dst_h=hardware_img->h; - glViewport(0, 0, (GLsizei)dst_w, (GLsizei)dst_h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glScalef (1.0, -1.0, 1.0); - //note: the max FOV is 90-degrees (this maximum applies to the longest screen dimension) - float fov; - if (environment_2d__screen_scaled_width>environment_2d__screen_scaled_height){ - fov=90.0f*((float)environment__window_width/(float)environment_2d__screen_scaled_width); - //convert fov from horizontal to vertical - fov=fov*((float)dst_h/(float)dst_w); - }else{ - fov=90.0f*((float)environment__window_height/(float)environment_2d__screen_scaled_height); - } - gluPerspective(fov, (GLfloat)dst_w / (GLfloat)dst_h, 0.1, 10000.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - //alert("3D rendering onto FBO not supported yet"); - } -} -render_state.view_mode=new_mode; -}//change_render_state - - -void set_render_source(int32 new_handle){ -if (new_handle==INVALID_HARDWARE_HANDLE){ - hardware_buffer_flush(); - render_state.source_handle=INVALID_HARDWARE_HANDLE; - return; -} -int32 current_handle; -current_handle=render_state.source_handle; - -if (current_handle==new_handle) return; - -hardware_buffer_flush(); - -hardware_img_struct* hardware_img; -hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,new_handle); -if (hardware_img->texture_handle==0) hardware_img_buffer_to_texture(new_handle); -glBindTexture (GL_TEXTURE_2D, hardware_img->texture_handle); -render_state.source_handle=new_handle; -render_state.source=&hardware_img->source_state; - -//note: some older systems require calling glTexParameterf after textures are rebound -if (framebufferobjects_supported==0){ - render_state.source->smooth_shrunk=SMOOTH_MODE__UNKNOWN; - render_state.source->smooth_stretched=SMOOTH_MODE__UNKNOWN; -} - -} - -void set_render_dest(int32 new_handle){ -if (new_handle==INVALID_HARDWARE_HANDLE){ - hardware_buffer_flush(); - render_state.dest_handle=INVALID_HARDWARE_HANDLE; - set_view(VIEW_MODE__UNKNOWN); - return; -} -//0=primary surface -static int32 current_handle; -current_handle=render_state.dest_handle; -if (new_handle==current_handle) return; -hardware_buffer_flush(); -set_view(VIEW_MODE__UNKNOWN); -if (new_handle==0){ - if (framebufferobjects_supported) glBindFramebufferEXT(GL_FRAMEBUFFER, 0); - render_state.dest=&dest_render_state0; -}else{ - static hardware_img_struct* hardware_img; - hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,new_handle); - //convert to regular texture first if necessary - if (hardware_img->texture_handle==0) hardware_img_buffer_to_texture(new_handle); - //does it have a dest context/FBO? if not create one - if (hardware_img->dest_context_handle==0){ - - static GLuint framebuffer_handle; - framebuffer_handle=0; - glGenFramebuffersEXT(1, &framebuffer_handle); - glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_handle); - hardware_img->dest_context_handle=framebuffer_handle; - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hardware_img->texture_handle, 0); - - //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - //glClear(GL_COLOR_BUFFER_BIT); - glColor4f(1.f, 1.f, 1.f, 1.f); - - set_render_source(INVALID_HARDWARE_HANDLE); - - }else{ - glBindFramebufferEXT(GL_FRAMEBUFFER, hardware_img->dest_context_handle); - } - render_state.dest=&hardware_img->dest_state; -} -render_state.dest_handle=new_handle; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - void hardware_img_put(int32 dst_x1,int32 dst_y1,int32 dst_x2,int32 dst_y2, - int32 src_img,int32 dst_img, - int32 src_x1,int32 src_y1,int32 src_x2,int32 src_y2, - int32 use_alpha, - int32 smooth - ){ - - if (dst_img<0) dst_img=0;//both layers render to the primary context - - //ensure dst_x1/y1 represent top-left co-ordinate of destination - static int32 swap_tmp; - if (dst_x2x1; - dst_y1=rect->y1; - dst_x2=rect->x2; - dst_y2=rect->y2; - } - - set_render_source(src_img); - - static hardware_img_struct* src_hardware_img; - static int32 src_h,src_w; - src_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,src_img); - src_h=src_hardware_img->h; - src_w=src_hardware_img->w; - - - if (smooth){ - set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__SMOOTH); - }else{ - set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__DONT_SMOOTH); - } - - if (use_alpha){ - set_alpha(ALPHA_MODE__BLEND); - }else{ - set_alpha(ALPHA_MODE__DONT_BLEND); - } - - set_depthbuffer(DEPTHBUFFER_MODE__OFF); - set_cull_mode(CULL_MODE__NONE); - - set_texture_wrap(TEXTURE_WRAP_MODE__DONT_WRAP); - - - - //adjust for render (x2 & y2 need to be one greater than the destination offset) - dst_x2++; dst_y2++; - -if (src_hardware_img->source_state.PO2_fix){ - src_w=src_hardware_img->PO2_w; - src_h=src_hardware_img->PO2_h; -} - - //calc source texture co-ordinates - static float x1f,y1f,x2f,y2f; - if (src_x1<=src_x2){ - x1f=((float)src_x1+0.01f)/(float)src_w; - x2f=((float)src_x2+0.99f)/(float)src_w; - }else{ - x2f=((float)src_x2+0.01f)/(float)src_w; - x1f=((float)src_x1+0.99f)/(float)src_w; - } - if (src_y1<=src_y2){ - y1f=((float)src_y1+0.01f)/(float)src_h; - y2f=((float)src_y2+0.99f)/(float)src_h; - }else{ - y2f=((float)src_y2+0.01f)/(float)src_h; - y1f=((float)src_y1+0.99f)/(float)src_h; - } - - //expand buffers if necessary - if ((hardware_buffer_vertices_count+18)>hardware_buffer_vertices_max){ - hardware_buffer_vertices_max=hardware_buffer_vertices_max*2+18; - hardware_buffer_vertices=(float*)realloc(hardware_buffer_vertices,hardware_buffer_vertices_max*sizeof(float)); - } - if ((hardware_buffer_texcoords_count+12)>hardware_buffer_texcoords_max){ - hardware_buffer_texcoords_max=hardware_buffer_texcoords_max*2+12; - hardware_buffer_texcoords=(float*)realloc(hardware_buffer_texcoords,hardware_buffer_texcoords_max*sizeof(float)); - } - hardware_buffer_vertices_int=(int32*)hardware_buffer_vertices; - - //clockwise - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; - - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; - - //hardware_buffer_flush(); //uncomment for debugging only - - } - - - - - - void hardware_img_tri2d(float dst_x1,float dst_y1,float dst_x2,float dst_y2,float dst_x3,float dst_y3, - int32 src_img,int32 dst_img, - float src_x1,float src_y1,float src_x2,float src_y2,float src_x3,float src_y3, - int32 use_alpha, - int32 smooth - ){ - - if (dst_img<0) dst_img=0;//both layers render to the primary context - - set_render_dest(dst_img); - set_view(VIEW_MODE__2D); - - if (dst_img){ - static hardware_img_struct* dst_hardware_img; - dst_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,dst_img); - -static int32 dst_w,dst_h; -dst_w=dst_hardware_img->w; -dst_h=dst_hardware_img->h; -//SEAMLESS adjustments: -//reduce texture co-ordinates (maintaining top-left) -//(todo) -//NON-SEAMLESS adjustments: -//Extend rhs/bottom row to fill extra pixel space -//calculate extents -int32 rx1; -int32 rx2; -rx1=dst_x1; -if (dst_x2rx2){ -rx2=dst_x2; -} -if (dst_x3>rx2){ -rx2=dst_x3; -} -float xr;//the multiplier for where we should be (1=no change) -if (rx1==rx2){ -xr=1.0f; -}else{ -xr=((float)rx2-(float)rx1+1.0)/((float)rx2-(float)rx1); -} -int32 ry1; -int32 ry2; -ry1=dst_y1; -if (dst_y2ry2){ -ry2=dst_y2; -} -if (dst_y3>ry2){ -ry2=dst_y3; -} -float yr;//the multiplier for where we should be (1=no change) -if (ry1==ry2){ -yr=1.0f; -}else{ -yr=((float)ry2-(float)ry1+1.0f)/((float)ry2-(float)ry1); -} -//apply multipliers so right-most and bottom-most rows will be filled -static int32 basex; -basex=rx1; -dst_x1=qbr_float_to_long( -((float)(dst_x1-rx1))*xr+(float)basex -); -dst_x2=qbr_float_to_long( -((float)(dst_x2-rx1))*xr+(float)basex -); -dst_x3=qbr_float_to_long( -((float)(dst_x3-rx1))*xr+(float)basex -); -static int32 basey; -basey=ry1; -dst_y1=qbr_float_to_long( -((float)(dst_y1-ry1))*yr+(float)basey -); -dst_y2=qbr_float_to_long( -((float)(dst_y2-ry1))*yr+(float)basey -); -dst_y3=qbr_float_to_long( -((float)(dst_y3-ry1))*yr+(float)basey -); - - }else{ //dest is 0 - -static int32 dst_w,dst_h; -dst_w=environment__window_width; -dst_h=environment__window_height; -//SEAMLESS adjustments: -//reduce texture co-ordinates (maintaining top-left) -//(todo) -//NON-SEAMLESS adjustments: -//Extend rhs/bottom row to fill extra pixel space -//calculate extents -int32 rx1; -int32 rx2; -rx1=dst_x1; -if (dst_x2rx2){ -rx2=dst_x2; -} -if (dst_x3>rx2){ -rx2=dst_x3; -} -float xr;//the multiplier for where we should be (1=no change) -if (rx1==rx2){ -xr=1.0f; -}else{ -xr=((float)rx2-(float)rx1+1.0)/((float)rx2-(float)rx1); -} -int32 ry1; -int32 ry2; -ry1=dst_y1; -if (dst_y2ry2){ -ry2=dst_y2; -} -if (dst_y3>ry2){ -ry2=dst_y3; -} -float yr;//the multiplier for where we should be (1=no change) -if (ry1==ry2){ -yr=1.0f; -}else{ -yr=((float)ry2-(float)ry1+1.0f)/((float)ry2-(float)ry1); -} -//apply multipliers so right-most and bottom-most rows will be filled -static int32 basex; -basex= -qbr_float_to_long( -((float)(rx1))*environment_2d__screen_x_scale+(float)environment_2d__screen_x1 -); -dst_x1= -basex+ -qbr_float_to_long( -((float)(dst_x1-rx1))*environment_2d__screen_x_scale*xr -); -dst_x2= -basex+ -qbr_float_to_long( -((float)(dst_x2-rx1))*environment_2d__screen_x_scale*xr -); -dst_x3= -basex+ -qbr_float_to_long( -((float)(dst_x3-rx1))*environment_2d__screen_x_scale*xr -); -static int32 basey; -basey= -qbr_float_to_long( -((float)(ry1))*environment_2d__screen_y_scale+(float)environment_2d__screen_y1 -); -dst_y1= -basey+ -qbr_float_to_long( -((float)(dst_y1-ry1))*environment_2d__screen_y_scale*yr -); -dst_y2= -basey+ -qbr_float_to_long( -((float)(dst_y2-ry1))*environment_2d__screen_y_scale*yr -); -dst_y3= -basey+ -qbr_float_to_long( -((float)(dst_y3-ry1))*environment_2d__screen_y_scale*yr -); - - } - - set_render_source(src_img); - - static hardware_img_struct* src_hardware_img; - static int32 src_h,src_w; - src_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,src_img); - src_h=src_hardware_img->h; - src_w=src_hardware_img->w; - - if (smooth==0){ - set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__DONT_SMOOTH); - } - if (smooth==1){ - set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__SMOOTH); - } - if (smooth==2){ - set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__DONT_SMOOTH); - } - if (smooth==3){ - set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__SMOOTH); - } - - set_texture_wrap(TEXTURE_WRAP_MODE__WRAP); - - if (use_alpha){ - set_alpha(ALPHA_MODE__BLEND); - }else{ - set_alpha(ALPHA_MODE__DONT_BLEND); - } - - set_depthbuffer(DEPTHBUFFER_MODE__OFF); - set_cull_mode(CULL_MODE__NONE); - -if (src_hardware_img->source_state.PO2_fix){ - src_w=src_hardware_img->PO2_w; - src_h=src_hardware_img->PO2_h; -} - - //calc source texture co-ordinates - static float x1f,y1f,x2f,y2f,x3f,y3f; - x1f=((float)src_x1+0.5f)/(float)src_w; - x2f=((float)src_x2+0.5f)/(float)src_w; - x3f=((float)src_x3+0.5f)/(float)src_w; - y1f=((float)src_y1+0.5f)/(float)src_h; - y2f=((float)src_y2+0.5f)/(float)src_h; - y3f=((float)src_y3+0.5f)/(float)src_h; - - - //expand buffers if necessary - if ((hardware_buffer_vertices_count+9)>hardware_buffer_vertices_max){ - hardware_buffer_vertices_max=hardware_buffer_vertices_max*2+9; - hardware_buffer_vertices=(float*)realloc(hardware_buffer_vertices,hardware_buffer_vertices_max*sizeof(float)); - } - if ((hardware_buffer_texcoords_count+6)>hardware_buffer_texcoords_max){ - hardware_buffer_texcoords_max=hardware_buffer_texcoords_max*2+6; - hardware_buffer_texcoords=(float*)realloc(hardware_buffer_texcoords,hardware_buffer_texcoords_max*sizeof(float)); - } - hardware_buffer_vertices_int=(int32*)hardware_buffer_vertices; - - - - //clockwise - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; - hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x3; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y3; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x3f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y3f; - - //hardware_buffer_flush(); //uncomment for debugging only - - } - -void clear_depthbuffer(int32 dst_img){ - hardware_buffer_flush(); - if (dst_img<0) dst_img=0;//both layers render to the primary context - set_render_dest(dst_img); - if (dst_img>0){ - hardware_img_requires_depthbuffer((hardware_img_struct*)list_get(hardware_img_handles,dst_img)); - } - glClear(GL_DEPTH_BUFFER_BIT); -} - - void hardware_img_tri3d(float dst_x1,float dst_y1,float dst_z1,float dst_x2,float dst_y2,float dst_z2,float dst_x3,float dst_y3,float dst_z3, - int32 src_img,int32 dst_img, - float src_x1,float src_y1,float src_x2,float src_y2,float src_x3,float src_y3, - int32 use_alpha, - int32 smooth, - int32 cull_mode, - int32 depthbuffer_mode - ){ - - if (dst_img<0) dst_img=0;//both layers render to the primary context - - set_render_dest(dst_img); - set_view(VIEW_MODE__3D); - - if (dst_img){ - static hardware_img_struct* dst_hardware_img; - dst_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,dst_img); - hardware_img_requires_depthbuffer(dst_hardware_img); - }else{ //dest is 0 - } - - set_render_source(src_img); - - static hardware_img_struct* src_hardware_img; - static int32 src_h,src_w; - src_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,src_img); - src_h=src_hardware_img->h; - src_w=src_hardware_img->w; - - if (smooth==0){ - set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__DONT_SMOOTH); - } - if (smooth==1){ - set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__SMOOTH); - } - if (smooth==2){ - set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__DONT_SMOOTH); - } - if (smooth==3){ - set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__SMOOTH); - } - - set_texture_wrap(TEXTURE_WRAP_MODE__WRAP); - - if (use_alpha){ - set_alpha(ALPHA_MODE__BLEND); - }else{ - set_alpha(ALPHA_MODE__DONT_BLEND); - } - - set_depthbuffer(depthbuffer_mode); - - //on frame buffers the 3D perspective is flipped vertically reversing the cull direction - if (dst_img>0){ - if (cull_mode==CULL_MODE__CLOCKWISE_ONLY){ - cull_mode=CULL_MODE__ANTICLOCKWISE_ONLY; - }else{ - if (cull_mode==CULL_MODE__ANTICLOCKWISE_ONLY) cull_mode=CULL_MODE__CLOCKWISE_ONLY; - } - } - - set_cull_mode(cull_mode); - -if (src_hardware_img->source_state.PO2_fix){ - src_w=src_hardware_img->PO2_w; - src_h=src_hardware_img->PO2_h; -} - - //calc source texture co-ordinates - static float x1f,y1f,x2f,y2f,x3f,y3f; - x1f=((float)src_x1+0.5f)/(float)src_w; - x2f=((float)src_x2+0.5f)/(float)src_w; - x3f=((float)src_x3+0.5f)/(float)src_w; - y1f=((float)src_y1+0.5f)/(float)src_h; - y2f=((float)src_y2+0.5f)/(float)src_h; - y3f=((float)src_y3+0.5f)/(float)src_h; - - //expand buffers if necessary - if ((hardware_buffer_vertices_count+9)>hardware_buffer_vertices_max){ - hardware_buffer_vertices_max=hardware_buffer_vertices_max*2+9; - hardware_buffer_vertices=(float*)realloc(hardware_buffer_vertices,hardware_buffer_vertices_max*sizeof(float)); - } - if ((hardware_buffer_texcoords_count+6)>hardware_buffer_texcoords_max){ - hardware_buffer_texcoords_max=hardware_buffer_texcoords_max*2+6; - hardware_buffer_texcoords=(float*)realloc(hardware_buffer_texcoords,hardware_buffer_texcoords_max*sizeof(float)); - } - - hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_y1; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_z1; - hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_y2; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_z2; - hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_x3; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_y3; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_z3; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; - hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x3f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y3f; - //hardware_buffer_flush(); //uncomment for debugging only - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static int32 software_screen_hardware_frame=0; - - static int32 in_GLUT_DISPLAY_REQUEST=0; - - void GLUT_DISPLAY_REQUEST(){ - - if (in_GLUT_DISPLAY_REQUEST){ - return; - } - in_GLUT_DISPLAY_REQUEST=1; - - //general use variables - static int32 i,i2,i3; - static int32 x,y,x2,y2; - - //determine which software frame to display - static int32 last_i;//the last software frame displayed - last_i=-1; - for (i2=0;i2<=2;i2++){ - if (display_frame[i2].state==DISPLAY_FRAME_STATE__DISPLAYING){ - last_i=i2; - } - } - i=-1; - static int64 highest_order; - highest_order=0; - if (last_i!=-1) highest_order=display_frame[last_i].order;//avoid any frames below the current one - for (i2=0;i2<=2;i2++){ - if (display_frame[i2].state==DISPLAY_FRAME_STATE__READY&&display_frame[i2].order>highest_order){ - highest_order=display_frame[i2].order; - i=i2; - } - } - if (i==-1) i=last_i; - if (i==-1){ - in_GLUT_DISPLAY_REQUEST=0; - return;//no frames exist yet, so screen size cannot be determined, therefore no action possible - } - if (i!=last_i){ - for (i2=0; i2<=2;i2++){ - if (display_frame[i2].order1) use_alpha=1; - - //put the software screen - hardware_img_put(0,0,environment_2d__screen_width-1,environment_2d__screen_height-1, - software_screen_hardware_frame, 0, - 0,0,f1->w-1,f1->h-1, - use_alpha,environment_2d__screen_smooth); - hardware_buffer_flush(); - }//level==displayorder_screen - - - if (level==displayorder_hardware||level==displayorder_hardware1){ - - static int32 dst; - dst=0; if (level==displayorder_hardware1) dst=-1; - - static int32 command; - command=0; - - if (first_hardware_layer_rendered==0){ - - if (first_hardware_command){ - - if (last_hardware_command_rendered){ - if (rerender_prev_hardware_frame){ - command=last_hardware_command_rendered; - }else{ - hardware_graphics_command_struct* last_hgc=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,last_hardware_command_rendered); - if (last_hgc==NULL) alert("Rendering: Last HGC is NULL!"); - command=last_hgc->next_command; - } - }else{ - command=first_hardware_command; - } - - //process/skip pending hardware puts before this frame's order value - while (command){ - hardware_graphics_command_struct* hgc=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,command); - if (hgc->ordercommand==HARDWARE_GRAPHICS_COMMAND__FREEIMAGE){ - free_hardware_img(hgc->src_img); - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__PUTIMAGE){ - if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required - hardware_img_put(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2, - hgc->src_img, hgc->dst_img, - hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2, - hgc->use_alpha,hgc->smooth); - } - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE){ - if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required - hardware_img_tri2d(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2,hgc->dst_x3,hgc->dst_y3, - hgc->src_img, hgc->dst_img, - hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, - hgc->use_alpha,hgc->smooth); - } - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE3D){ - if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required - hardware_img_tri3d(hgc->dst_x1,hgc->dst_y1,hgc->dst_z1,hgc->dst_x2,hgc->dst_y2,hgc->dst_z2,hgc->dst_x3,hgc->dst_y3,hgc->dst_z3, - hgc->src_img, hgc->dst_img, - hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, - hgc->use_alpha,hgc->smooth,hgc->cull_mode,hgc->depthbuffer_mode); - } - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__CLEAR_DEPTHBUFFER){ - if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required - clear_depthbuffer(hgc->dst_img); - } - } - - last_hardware_command_rendered=command; - if (next_hardware_command_to_remove==0) next_hardware_command_to_remove=command; - command=hgc->next_command; - hgc->remove=1; - }else{ - goto found_command_from_current_order; - } - } - found_command_from_current_order:; - - }//first_hardware_command - - - first_hardware_layer_command=command; - }else{ - command=first_hardware_layer_command; - } - - //process pending hardware puts for this frame's order value - while (command){ - hardware_graphics_command_struct* hgc=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,command); - if (hgc==NULL){ - - hardware_graphics_command_struct* hgcx=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,next_hardware_command_to_remove); - alert(order); - alert(hgcx->order); - alert(command); - alert ("Renderer: Command does not exist."); - } - if (hgc->order==order){ - if (first_command_prev_order==0) first_command_prev_order=command; - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__FREEIMAGE&&rerender_prev_hardware_frame==0&&first_hardware_layer_rendered==0){ - free_hardware_img(hgc->src_img); - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__PUTIMAGE){ - if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ - if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ - hardware_img_put(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2, - hgc->src_img, hgc->dst_img, - hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2, - hgc->use_alpha,hgc->smooth); - } - } - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE){ - if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ - if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ - hardware_img_tri2d(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2,hgc->dst_x3,hgc->dst_y3, - hgc->src_img, hgc->dst_img, - hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, - hgc->use_alpha,hgc->smooth); - } - } - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE3D){ - if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ - if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ - hardware_img_tri3d(hgc->dst_x1,hgc->dst_y1,hgc->dst_z1,hgc->dst_x2,hgc->dst_y2,hgc->dst_z2,hgc->dst_x3,hgc->dst_y3,hgc->dst_z3, - hgc->src_img, hgc->dst_img, - hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, - hgc->use_alpha,hgc->smooth,hgc->cull_mode,hgc->depthbuffer_mode); - } - } - } - - if (hgc->command==HARDWARE_GRAPHICS_COMMAND__CLEAR_DEPTHBUFFER){ - if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ - if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ - clear_depthbuffer(hgc->dst_img); - } - } - } - - last_hardware_command_rendered=command; - if (next_hardware_command_to_remove==0) next_hardware_command_to_remove=command;//!!!! should be prev to this command - command=hgc->next_command; - hgc->remove=1; - }else{ - goto finished_all_commands_for_current_frame; - } - - - } - finished_all_commands_for_current_frame:; - - first_hardware_layer_rendered=1; - - - - hardware_buffer_flush(); - }//level==displayorder_hardware||level==displayorder_hardware1 - - - if (level==5){ - - if (environment_2d__letterbox){ - - //create a black texture (if not yet created) - static uint32 black_pixel=0x00000000; - static int32 black_texture=0; - if (black_texture==0){ - black_texture=new_hardware_img(1,1,&black_pixel,NULL); - } - - if (environment_2d__letterbox==1){ - //vertical stripes - hardware_img_put(((float)-environment_2d__screen_x1)/environment_2d__screen_x_scale-1.0f,0,-1,environment_2d__screen_height-1, - black_texture, 0, - 0,0,0,0, - 0,0); - hardware_img_put(environment_2d__screen_width,0,(((float)-environment_2d__screen_x1)+(float)environment__window_width-1.0f)/environment_2d__screen_x_scale+1.0f,environment_2d__screen_height-1, - black_texture, 0, - 0,0,0,0, - 0,0); - }else{ - //horizontal stripes - hardware_img_put(0,((float)-environment_2d__screen_y1)/environment_2d__screen_y_scale-1.0f,environment_2d__screen_width-1,-1, - black_texture, 0, - 0,0,0,0, - 0,0); - hardware_img_put(0,environment_2d__screen_height,environment_2d__screen_width-1,(((float)-environment_2d__screen_y1)+(float)environment__window_height-1.0f)/environment_2d__screen_y_scale+1.0f, - black_texture, 0, - 0,0,0,0, - 0,0); - } - hardware_buffer_flush(); - }//letterbox - - }//level==5 - - - }//level!=0 - }//level loop - - last_rendered_hardware_display_frame_order=last_hardware_display_frame_order; - - - - if (suspend_program){ //Otherwise skipped SUB__GL content becomes "invisible" - //... - }else{ - glutSwapBuffers(); - } - - in_GLUT_DISPLAY_REQUEST=0; - - }//GLUT_DISPLAY_REQUEST - - - - - - void GLUT_MouseButton_Up(int glut_button,int x,int y){ -#ifdef QB64_GLUT - - int32 i; - int32 button; - button=1;//default - if (glut_button==GLUT_LEFT_BUTTON) button=1; - if (glut_button==GLUT_RIGHT_BUTTON) button=3; - if (glut_button==GLUT_MIDDLE_BUTTON) button=2; - if (glut_button==4) button=4; - if (glut_button==5) button=5; - i=(last_mouse_message+1)&65535; - if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message - mouse_messages[i].movementx=0; - mouse_messages[i].movementy=0; - mouse_messages[i].x=x; - mouse_messages[i].y=y; - mouse_messages[i].buttons=mouse_messages[last_mouse_message].buttons; - if (mouse_messages[i].buttons&(1<<(button-1))) mouse_messages[i].buttons^=(1<<(button-1)); - last_mouse_message=i; - if (device_last){//core devices required? - if ((button>=1)&&(button<=3)){ - button--; - static device_struct *d; - d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+button)=0; - d->queued_events++; - }//valid range - }//core devices required - -#endif - } - - void GLUT_MouseButton_Down(int glut_button,int x,int y){ -#ifdef QB64_GLUT - - int32 i; - int32 button; - button=1;//default - if (glut_button==GLUT_LEFT_BUTTON) button=1; - if (glut_button==GLUT_RIGHT_BUTTON) button=3; - if (glut_button==GLUT_MIDDLE_BUTTON) button=2; - if (glut_button==4) button=4; - if (glut_button==5) button=5; - i=(last_mouse_message+1)&65535; - if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message - mouse_messages[i].movementx=0; - mouse_messages[i].movementy=0; - mouse_messages[i].x=x; - mouse_messages[i].y=y; - mouse_messages[i].buttons=mouse_messages[last_mouse_message].buttons; - mouse_messages[i].buttons|=(1<<(button-1)); - last_mouse_message=i; - if (device_last){//core devices required? - if ((button>=1)&&(button<=3)){ - button--; - static device_struct *d; - d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(d->events+(d->queued_events*d->event_size)+button)=1; - d->queued_events++; - //1-3 - }else{ - //not 1-3 - //mouse wheel? - if ((button>=4)&&(button<=5)){ - static float f; - if (button==4) f=-1; else f=1; - static device_struct *d; - d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+(3-1)*4)=f; - d->queued_events++; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+(3-1)*4)=0; - d->queued_events++; - }//4-5 - }//not 1-3 - }//core devices required -#endif - } - - void GLUT_MOUSE_FUNC(int glut_button,int state,int x,int y){ -#ifdef QB64_GLUT - if (state==GLUT_DOWN) GLUT_MouseButton_Down(glut_button,x,y); - if (state==GLUT_UP) GLUT_MouseButton_Up(glut_button,x,y); -#endif - } - - void GLUT_MOTION_FUNC(int x, int y){ - - static int32 i,last_i; - static int32 xrel=0,yrel=0; - //message #1 - last_i=last_mouse_message; - i=(last_mouse_message+1)&65535; - if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message - mouse_messages[i].x=x; - mouse_messages[i].y=y; - if (mouseinput_ignoremovement){ - mouseinput_ignoremovement--; - mouse_messages[i].movementx=0; - mouse_messages[i].movementy=0; - }else{ - mouse_messages[i].movementx=xrel; - mouse_messages[i].movementy=yrel; - } - mouse_messages[i].buttons=mouse_messages[last_i].buttons; - last_mouse_message=i; - //message #2 (clears movement values to avoid confusion) - last_i=last_mouse_message; - i=(last_mouse_message+1)&65535; - if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message - mouse_messages[i].x=x; - mouse_messages[i].y=y; - mouse_messages[i].movementx=0; - mouse_messages[i].movementy=0; - mouse_messages[i].buttons=mouse_messages[last_i].buttons; - last_mouse_message=i; - if (device_last){//core devices required? - if (!device_mouse_relative){ - static device_struct *d; - d=&devices[2];//mouse - static uint8 *cp,*cp2; - - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - static float fx,fy; - static int32 z; - fx=x; - fx-=x_offset; - z=x_monitor-x_offset*2; - if (fx<0) fx=0; - if (fx>=z) fx=z-1; - fx=fx/(float)(z-1);//0 to 1 - fx*=2.0;//0 to 2 - fx-=1.0;//-1 to 1 - fy=y; - fy-=y_offset; - z=y_monitor-y_offset*2; - if (fy<0) fy=0; - if (fy>=z) fy=z-1; - fy=fy/(float)(z-1);//0 to 1 - fy*=2.0;//0 to 2 - fy-=1.0;//-1 to 1 - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton)=fx; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+4)=fy; - d->queued_events++; - }else{ - static device_struct *d; - d=&devices[2];//mouse - static uint8 *cp,*cp2; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - static float fx,fy; - static int32 z; - fx=xrel; - fy=yrel; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4)=fx; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+4)=fy; - d->queued_events++; - if (d->queued_events==d->max_events){//expand/shift event buffer - if (d->max_events>=QUEUED_EVENTS_LIMIT){ - //discard base message - memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); - d->queued_events--; - }else{ - cp=(uint8*)calloc(d->max_events*2,d->event_size); - memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events - cp2=d->events; - d->events=cp; - free(cp2); - d->max_events*=2; - } - } - memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event - *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index - //make required changes - fx=0; - fy=0; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4)=fx; - *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+4)=fy; - d->queued_events++; - } - }//core devices required - } - - void GLUT_PASSIVEMOTION_FUNC(int x, int y){ - GLUT_MOTION_FUNC(x,y); - } - - - void GLUT_MOUSEWHEEL_FUNC(int wheel, int direction, int x, int y){ -#ifdef QB64_GLUT - //Note: freeglut specific, limited documentation existed so the following research was done: - // qbs_print(qbs_str(wheel),NULL); <-- was always 0 [could 1 indicate horizontal wheel?] - // qbs_print(qbs_str(direction),NULL); <-- 1(up) or -1(down) - // qbs_print(qbs_str(x),NULL); <--mouse x,y co-ordinates - // qbs_print(qbs_str(y),1); < - if (direction>0){GLUT_MouseButton_Down(4,x,y); GLUT_MouseButton_Up(4,x,y);} - if (direction<0){GLUT_MouseButton_Down(5,x,y); GLUT_MouseButton_Up(5,x,y);} -#endif - } - - - - - - - - - +#include "libqb/gui.cpp" void sub__title(qbs *title){ if (new_error) return; @@ -31689,6 +29236,13 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; lock_display_required=1; +#ifndef QB64_GUI + //normally MAIN_LOOP() is launched in a separate thread to reserve the primary thread for GLUT + //that is not required, so run MAIN_LOOP() in our primary thread + MAIN_LOOP(); + exit(0); +#endif + #ifdef QB64_WINDOWS _beginthread(MAIN_LOOP_WINDOWS,0,NULL); #else @@ -31699,8 +29253,11 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; #endif if (!screen_hide) create_window=1; + while (!create_window){Sleep(100);} + +#ifdef QB64_GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); @@ -31753,6 +29310,8 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; glutMainLoop(); +#endif //QB64_GLUT + } @@ -31786,8 +29345,6 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; if (!exit_blocked) goto end_program; } - //GLUT_DISPLAY_REQUEST(); - //glutMainLoopEvent(); //update timer bytes in cmem static uint32 cmem_ticks; @@ -31886,9 +29443,11 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; code=buffer[start]; start++; + #ifdef QB64_GUI + if (code==77){//M (mousemove) - sscanf (buffer+start,"%d,%d",&v1,&v2); - GLUT_MOTION_FUNC(v1,v2); + sscanf (buffer+start,"%d,%d",&v1,&v2); + GLUT_MOTION_FUNC(v1,v2); }//M if (code==76){//L (left mouse button) @@ -31900,6 +29459,7 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; GLUT_MouseButton_Up(GLUT_LEFT_BUTTON,v1,v2); } + if (code==68){//D (key down) sscanf (buffer+start,"%d",&v1); keydown_vk(v1); @@ -31909,6 +29469,8 @@ render_state.cull_mode=CULL_MODE__UNKNOWN; keyup_vk(v1); }//U + #endif + start=bi+1; goto nextcommand; diff --git a/internal/c/libqb/gui.cpp b/internal/c/libqb/gui.cpp new file mode 100644 index 000000000..56f6623ee --- /dev/null +++ b/internal/c/libqb/gui.cpp @@ -0,0 +1,2179 @@ + int32 displayorder_screen=1; + int32 displayorder_hardware=2; + int32 displayorder_glrender=3; + int32 displayorder_hardware1=4; + + //sub__displayorder( 1 , 2 , 4 , 3 ); + //id.specialformat = "[{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}[,{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}[,{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}[,{_SCREEN|_HARDWARE|_HARDWARE1|_GLRENDER}]]]]" + void sub__displayorder(int32 method1,int32 method2,int32 method3,int32 method4){ + + //check no value has been used twice + if (method1!=0) if (method1==method2||method1==method3||method1==method4){error(5); return;} + if (method2!=0) if (method2==method1||method2==method3||method2==method4){error(5); return;} + if (method3!=0) if (method3==method1||method3==method2||method3==method4){error(5); return;} + if (method4!=0) if (method4==method1||method4==method2||method4==method3){error(5); return;} + displayorder_screen=0; + displayorder_hardware=0; + displayorder_hardware1=0; + displayorder_glrender=0; + static int32 i,method; + for (i=1;i<=4;i++){ + if (i==1) method=method1; + if (i==2) method=method2; + if (i==3) method=method3; + if (i==4) method=method4; + if (method==1) displayorder_screen=i; + if (method==2) displayorder_hardware=i; + if (method==3) displayorder_hardware1=i; + if (method==4) displayorder_glrender=i; + } + } + + //int32 gl_render_method=2; //1=behind, 2=ontop[default], 3=only + void sub__glrender(int32 method){ + //gl_render_method=method; + if (method==1) sub__displayorder(4,1,2,3); + if (method==2) sub__displayorder(1,2,4,3); + if (method==3) sub__displayorder(4,0,0,0); + } + + +#ifndef QB64_GUI //begin stubs + + + + +#else //end stubs + + + + + + void GLUT_RESHAPE_FUNC(int width, int height){ + resize_event_x=width; resize_event_y=height; + resize_event=-1; + display_x_prev=display_x,display_y_prev=display_y; + display_x=width; display_y=height; + resize_pending=0; + os_resize_event=1; + set_view(VIEW_MODE__UNKNOWN); + //***glutReshapeWindow(...) has no effect if called + // within GLUT_RESHAPE_FUNC*** + } + + + + + //displaycall is the window of time to update our display + + +#ifdef DEPENDENCY_GL + extern void SUB__GL(); +#endif + + + + + + + + + +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 + + + + /* reference + struct hardware_img_struct{ + int32 w; + int32 h; + int32 texture_handle; + int32 dest_context_handle;//used when rendering other images onto this image + int32 temp;//if =1, delete immediately after use + } + list *hardware_img_handles=NULL; + */ + + + + void free_hardware_img(int32 handle){ + + //alert("free_hardware_img: entered"); + + static hardware_img_struct* hardware_img; + hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle); + + if (hardware_img==NULL) alert("free_hardware_img: image does not exist"); + + if (hardware_img->dest_context_handle){ + GLuint context=(GLuint)hardware_img->dest_context_handle; + glDeleteFramebuffersEXT(1, &context); + } + if (hardware_img->depthbuffer_handle){ + GLuint depthbuffer_handle=(GLuint)hardware_img->depthbuffer_handle; + glDeleteFramebuffersEXT(1, &depthbuffer_handle); + } + GLuint texture=(GLuint)hardware_img->texture_handle; + glDeleteTextures(1, &texture); + + //if image has not been used, it may still have buffered pixel content + if (hardware_img->software_pixel_buffer!=NULL) free(hardware_img->software_pixel_buffer); + + list_remove(hardware_img_handles,handle); + } + + + /* + int32 new_hardware_frame(int32 x, int32 y){ + int32 handle=new_hardware_frame_handle(); + glBindTexture (GL_TEXTURE_2D, handle); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + return handle; + } + + void free_hardware_frame(int32 handle){ + GLuint texture=(GLuint)handle; + glDeleteTextures(1, &texture); + } + */ + + + + + void prepare_environment_2d(){//called prior to rendering 2D content + + //precalculate critical dimensions, offsets & ratios + + static int32 can_scale;//can the screen be scaled on the window + can_scale=0; + static int32 need_square_pixels;//do we need square_pixels? if not we can stretch the screen + need_square_pixels=0; + + environment_2d__screen_smooth=0; + + environment_2d__letterbox=0; + + if (full_screen>0){//in full screen + //reference: ---int32 full_screen_set=-1;//0(windowed),1(stretched/closest),2(1:1)--- + can_scale=1; + if (full_screen==2) need_square_pixels=1; + //note: 'letter-boxing' is only requred where the size of the window cannot be controlled, and the only place where this is the + // case is full screen mode _SQUAREPIXELS + environment_2d__screen_smooth=fullscreen_smooth; + }else{//windowed + if (resize_auto>0){//1=STRETCH,2=SMOOTH + can_scale=1; + if (resize_auto==2) environment_2d__screen_smooth=1; + //note: screen will fix its aspect ratio automatically, so there is no need to enforce squarepixels + } + } + + if (environment_2d__screen_width==environment__window_width && + environment_2d__screen_height==environment__window_height){ + //screen size matches window + environment_2d__screen_x1=0; + environment_2d__screen_y1=0; + environment_2d__screen_x2=environment_2d__screen_width-1; + environment_2d__screen_y2=environment_2d__screen_height-1; + environment_2d__screen_x_scale=1.0f; + environment_2d__screen_y_scale=1.0f; + environment_2d__screen_scaled_width=environment_2d__screen_width; + environment_2d__screen_scaled_height=environment_2d__screen_height; + environment_2d__screen_smooth=0;//no smoothing required + }else{ + //screen size does not match + //calculate ratios + static float window_ratio; + static float screen_ratio; + window_ratio=(float)environment__window_width/(float)environment__window_height; + screen_ratio=(float)environment_2d__screen_width/(float)environment_2d__screen_height; + if (can_scale==0){ + //screen will appear in the top-left of the window with blank space on the bottom & right + environment_2d__screen_x1=0; + environment_2d__screen_y1=0; + environment_2d__screen_x2=environment_2d__screen_width-1; + environment_2d__screen_y2=environment_2d__screen_height-1; + goto cant_scale; + } + if (need_square_pixels==0||(window_ratio==screen_ratio)){ + //can stretch, no 'letter-box' required + environment_2d__screen_x1=0; + environment_2d__screen_y1=0; + environment_2d__screen_x2=environment__window_width-1; + environment_2d__screen_y2=environment__window_height-1; + }else{ + //'letter-box' required + //this section needs revision + static float x_scale,y_scale; + static int32 x1,y1,x2,y2,z,x_limit,y_limit,x_offset,y_offset; + //x_scale=(float)environment_2d__screen_width/(float)environment__window_width; + //y_scale=(float)environment_2d__screen_height/(float)environment__window_height; + //x_offset=0; y_offset=0; + + x1=0; y1=0; x2=environment__window_width-1; y2=environment__window_height-1; + //x_limit=x2; y_limit=y2; + if (window_ratio>screen_ratio){ + //pad sides + z=(float)environment__window_height*screen_ratio;//new width + x1=environment__window_width/2-z/2; + x2=x1+z-1; + environment_2d__letterbox=1;//vertical black stripes required + //x_offset=-x1; x_scale=(float)environment_2d__screen_width/(float)z; x_limit=z-1; + }else{ + //pad top/bottom + z=(float)environment__window_width/screen_ratio;//new height + y1=environment__window_height/2-z/2; + y2=y1+z-1; + environment_2d__letterbox=2;//horizontal black stripes required + //y_offset=-y1; y_scale=(float)environment_2d__screen_height/(float)z; y_limit=z-1; + } + environment_2d__screen_x1=x1; + environment_2d__screen_y1=y1; + environment_2d__screen_x2=x2; + environment_2d__screen_y2=y2; + } + cant_scale: + environment_2d__screen_scaled_width=environment_2d__screen_x2-environment_2d__screen_x1+1; + environment_2d__screen_scaled_height=environment_2d__screen_y2-environment_2d__screen_y1+1; + environment_2d__screen_x_scale=(float)environment_2d__screen_scaled_width/(float)environment_2d__screen_width; + environment_2d__screen_y_scale=(float)environment_2d__screen_scaled_height/(float)environment_2d__screen_height; + } + + }//prepare_environment_2d + + + int32 environment_2d__get_window_x1_coord(int32 x){ + return qbr_float_to_long(((float)x)*environment_2d__screen_x_scale)+environment_2d__screen_x1; + } + int32 environment_2d__get_window_y1_coord(int32 y){ + return qbr_float_to_long((float)y*environment_2d__screen_y_scale)+environment_2d__screen_y1; + } + int32 environment_2d__get_window_x2_coord(int32 x){ + return qbr_float_to_long(((float)x+1.0f)*environment_2d__screen_x_scale-1.0f)+environment_2d__screen_x1; + } + + int32 environment_2d__get_window_y2_coord(int32 y){ + return qbr_float_to_long(((float)y+1.0f)*environment_2d__screen_y_scale-1.0f)+environment_2d__screen_y1; + } + + struct environment_2d__window_rect_struct{ + int32 x1; + int32 y1; + int32 x2; + int32 y2; + }; + + //this functions returns a constant rect dimensions to stop warping of image + environment_2d__window_rect_struct tmp_rect; + environment_2d__window_rect_struct *environment_2d__screen_to_window_rect(int32 x1,int32 y1,int32 x2,int32 y2){ + tmp_rect.x1=qbr_float_to_long(((float)x1)*environment_2d__screen_x_scale)+environment_2d__screen_x1; + tmp_rect.y1=qbr_float_to_long(((float)y1)*environment_2d__screen_y_scale)+environment_2d__screen_y1; + static int32 w,h; + w=abs(x2-x1)+1; h=abs(y2-y1)+1; + //force round upwards to correct gaps when tiling + w=((float)w)*environment_2d__screen_x_scale+0.99f; + h=((float)h)*environment_2d__screen_y_scale+0.99f; + tmp_rect.x2=w-1+tmp_rect.x1; + tmp_rect.y2=h-1+tmp_rect.y1; + //(code which doesn't support tiling) + //tmp_rect.x2=qbr_float_to_long(((float)w)*environment_2d__screen_x_scale-1.0f)+tmp_rect.x1; + //tmp_rect.y2=qbr_float_to_long(((float)h)*environment_2d__screen_y_scale-1.0f)+tmp_rect.y1; + return &tmp_rect; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +float *hardware_buffer_vertices=(float*)malloc(sizeof(float)*1); +int32 *hardware_buffer_vertices_int; + +int32 hardware_buffer_vertices_max=1; +int32 hardware_buffer_vertices_count=0; + +float *hardware_buffer_texcoords=(float*)malloc(sizeof(float)*1); +int32 hardware_buffer_texcoords_max=1; +int32 hardware_buffer_texcoords_count=0; + +void hardware_buffer_flush(){ + if (hardware_buffer_vertices_count){ + //ref: http://stackoverflow.com/questions/5009014/draw-square-with-opengl-es-for-ios + if (hardware_buffer_vertices_count==hardware_buffer_texcoords_count){ + glVertexPointer(2, GL_INT, 2*sizeof(GL_INT), (int32*)hardware_buffer_vertices); //http://www.opengl.org/sdk/docs/man2/xhtml/glVertexPointer.xml + glTexCoordPointer(2, GL_FLOAT, 2*sizeof(GL_FLOAT), hardware_buffer_texcoords); //http://www.opengl.org/sdk/docs/man2/xhtml/glTexCoordPointer.xml + glDrawArrays(GL_TRIANGLES, 0, hardware_buffer_vertices_count/2);//start index, number of indexes + }else{ + glVertexPointer(3, GL_FLOAT, 3*sizeof(GL_FLOAT), hardware_buffer_vertices); //http://www.opengl.org/sdk/docs/man2/xhtml/glVertexPointer.xml + glTexCoordPointer(2, GL_FLOAT, 2*sizeof(GL_FLOAT), hardware_buffer_texcoords); //http://www.opengl.org/sdk/docs/man2/xhtml/glTexCoordPointer.xml + glDrawArrays(GL_TRIANGLES, 0, hardware_buffer_vertices_count/3);//start index, number of indexes + } + hardware_buffer_vertices_count=0; + hardware_buffer_texcoords_count=0; + } +} + + + + +void set_smooth(int32 new_mode_shrunk,int32 new_mode_stretched){ +static int32 current_mode_shrunk; +current_mode_shrunk=render_state.source->smooth_shrunk; +static int32 current_mode_stretched; +current_mode_stretched=render_state.source->smooth_stretched; +if (new_mode_shrunk==current_mode_shrunk&&new_mode_stretched==current_mode_stretched) return; +hardware_buffer_flush(); +if (new_mode_shrunk==SMOOTH_MODE__DONT_SMOOTH){ + if (render_state.source->PO2_fix==PO2_FIX__MIPMAPPED){ + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + }else{ + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } +} +if (new_mode_shrunk==SMOOTH_MODE__SMOOTH){ + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} +if (new_mode_stretched==SMOOTH_MODE__DONT_SMOOTH){ + if (render_state.source->PO2_fix==PO2_FIX__MIPMAPPED){ + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + }else{ + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } +} +if (new_mode_stretched==SMOOTH_MODE__SMOOTH){ + glTexParameterf ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} +render_state.source->smooth_shrunk=new_mode_shrunk; +render_state.source->smooth_stretched=new_mode_stretched; +} + +void set_texture_wrap(int32 new_mode){ +static int32 current_mode; +current_mode=render_state.source->texture_wrap; +if (new_mode==current_mode) return; +hardware_buffer_flush(); +if (new_mode==TEXTURE_WRAP_MODE__DONT_WRAP){ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} +if (new_mode==TEXTURE_WRAP_MODE__WRAP){ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +} +render_state.source->texture_wrap=new_mode; +} + +void set_alpha(int32 new_mode){ +static int32 current_mode; +current_mode=render_state.use_alpha; +if (new_mode==current_mode) return; +hardware_buffer_flush(); +if (new_mode==ALPHA_MODE__DONT_BLEND){ + glDisable(GL_BLEND); +} +if (new_mode==ALPHA_MODE__BLEND){ + glEnable(GL_BLEND); + if (framebufferobjects_supported){ + //glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + }else{ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } +} +render_state.use_alpha=new_mode; +} + +void set_depthbuffer(int32 new_mode){ +static int32 current_mode; +current_mode=render_state.depthbuffer_mode; +if (new_mode==current_mode) return; +hardware_buffer_flush(); +if (new_mode==DEPTHBUFFER_MODE__OFF){ + glDisable(GL_DEPTH_TEST); + glAlphaFunc(GL_ALWAYS, 0); +} +if (new_mode==DEPTHBUFFER_MODE__ON){ + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glAlphaFunc(GL_GREATER, 0.001); + glEnable(GL_ALPHA_TEST); +} +if (new_mode==DEPTHBUFFER_MODE__LOCKED){ + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glAlphaFunc(GL_ALWAYS, 0); +} +render_state.depthbuffer_mode=new_mode; +} + +void set_cull_mode(int32 new_mode){ +static int32 current_mode; +current_mode=render_state.cull_mode; +if (new_mode==current_mode) return; +hardware_buffer_flush(); +if (new_mode==CULL_MODE__NONE){ + glDisable(GL_CULL_FACE); +} +if (new_mode==CULL_MODE__CLOCKWISE_ONLY){ + glFrontFace(GL_CW); + if (current_mode!=CULL_MODE__ANTICLOCKWISE_ONLY) glEnable(GL_CULL_FACE); +} +if (new_mode==CULL_MODE__ANTICLOCKWISE_ONLY){ + glFrontFace(GL_CCW); + if (current_mode!=CULL_MODE__CLOCKWISE_ONLY) glEnable(GL_CULL_FACE); +} +render_state.cull_mode=new_mode; +} + +void set_view(int32 new_mode){ //set view can only be called after the correct destination is chosen +static int32 current_mode; +current_mode=render_state.view_mode; +if (new_mode==current_mode) return; +hardware_buffer_flush(); +if (new_mode==VIEW_MODE__RESET){ + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_LIGHTING); + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glDisable(GL_CULL_FACE); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glAlphaFunc(GL_ALWAYS, 0); + if (framebufferobjects_supported) glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + glBindTexture (GL_TEXTURE_2D, 0); + glClear(GL_DEPTH_BUFFER_BIT); + glColor4f(1.f, 1.f, 1.f, 1.f); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + //invalidate current states + set_alpha(ALPHA_MODE__UNKNOWN); + set_depthbuffer(DEPTHBUFFER_MODE__UNKNOWN); + set_cull_mode(CULL_MODE__UNKNOWN); + set_render_source(INVALID_HARDWARE_HANDLE); + set_render_dest(INVALID_HARDWARE_HANDLE); + new_mode=VIEW_MODE__UNKNOWN;//resets are performed before unknown operations are executed +} +if (new_mode==VIEW_MODE__2D){ + if (current_mode!=VIEW_MODE__3D){ + glColor4f(1.f, 1.f, 1.f, 1.f); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + set_alpha(ALPHA_MODE__BLEND); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glCullFace(GL_BACK); + } + + if (render_state.dest_handle==0){ + static int32 dst_w,dst_h; + dst_w=environment__window_width; + dst_h=environment__window_height; + +//alert(dst_w); +//alert(dst_h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0, dst_w, 0.0, dst_h, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glScalef(1, -1, 1);//flip vertically + glTranslatef(0, -dst_h, 0);//move to new vertical position + glViewport(0,0,dst_w,dst_h); + }else{ + static hardware_img_struct* hardware_img; + hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,render_state.dest_handle); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, hardware_img->w, 0, hardware_img->h); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0,0,hardware_img->w,hardware_img->h); + } +} +if (new_mode==VIEW_MODE__3D){ + if (current_mode!=VIEW_MODE__2D){ + glColor4f(1.f, 1.f, 1.f, 1.f); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + set_alpha(ALPHA_MODE__BLEND); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glCullFace(GL_BACK); + } + if (render_state.dest_handle==0){ + static int32 dst_w,dst_h; + dst_w=environment__window_width; + dst_h=environment__window_height; + glViewport(0, 0, (GLsizei)dst_w, (GLsizei)dst_h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + //note: the max FOV is 90-degrees (this maximum applies to the longest screen dimension) + float fov; + if (environment_2d__screen_scaled_width>environment_2d__screen_scaled_height){ + fov=90.0f*((float)environment__window_width/(float)environment_2d__screen_scaled_width); + //convert fov from horizontal to vertical + fov=fov*((float)dst_h/(float)dst_w); + }else{ + fov=90.0f*((float)environment__window_height/(float)environment_2d__screen_scaled_height); + } + gluPerspective(fov, (GLfloat)dst_w / (GLfloat)dst_h, 0.1, 10000.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + }else{ + + static hardware_img_struct* hardware_img; + hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,render_state.dest_handle); + + static int32 dst_w,dst_h; + dst_w=hardware_img->w; + dst_h=hardware_img->h; + glViewport(0, 0, (GLsizei)dst_w, (GLsizei)dst_h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glScalef (1.0, -1.0, 1.0); + //note: the max FOV is 90-degrees (this maximum applies to the longest screen dimension) + float fov; + if (environment_2d__screen_scaled_width>environment_2d__screen_scaled_height){ + fov=90.0f*((float)environment__window_width/(float)environment_2d__screen_scaled_width); + //convert fov from horizontal to vertical + fov=fov*((float)dst_h/(float)dst_w); + }else{ + fov=90.0f*((float)environment__window_height/(float)environment_2d__screen_scaled_height); + } + gluPerspective(fov, (GLfloat)dst_w / (GLfloat)dst_h, 0.1, 10000.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + //alert("3D rendering onto FBO not supported yet"); + } +} +render_state.view_mode=new_mode; +}//change_render_state + + +void set_render_source(int32 new_handle){ +if (new_handle==INVALID_HARDWARE_HANDLE){ + hardware_buffer_flush(); + render_state.source_handle=INVALID_HARDWARE_HANDLE; + return; +} +int32 current_handle; +current_handle=render_state.source_handle; + +if (current_handle==new_handle) return; + +hardware_buffer_flush(); + +hardware_img_struct* hardware_img; +hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,new_handle); +if (hardware_img->texture_handle==0) hardware_img_buffer_to_texture(new_handle); +glBindTexture (GL_TEXTURE_2D, hardware_img->texture_handle); +render_state.source_handle=new_handle; +render_state.source=&hardware_img->source_state; + +//note: some older systems require calling glTexParameterf after textures are rebound +if (framebufferobjects_supported==0){ + render_state.source->smooth_shrunk=SMOOTH_MODE__UNKNOWN; + render_state.source->smooth_stretched=SMOOTH_MODE__UNKNOWN; +} + +} + +void set_render_dest(int32 new_handle){ +if (new_handle==INVALID_HARDWARE_HANDLE){ + hardware_buffer_flush(); + render_state.dest_handle=INVALID_HARDWARE_HANDLE; + set_view(VIEW_MODE__UNKNOWN); + return; +} +//0=primary surface +static int32 current_handle; +current_handle=render_state.dest_handle; +if (new_handle==current_handle) return; +hardware_buffer_flush(); +set_view(VIEW_MODE__UNKNOWN); +if (new_handle==0){ + if (framebufferobjects_supported) glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + render_state.dest=&dest_render_state0; +}else{ + static hardware_img_struct* hardware_img; + hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,new_handle); + //convert to regular texture first if necessary + if (hardware_img->texture_handle==0) hardware_img_buffer_to_texture(new_handle); + //does it have a dest context/FBO? if not create one + if (hardware_img->dest_context_handle==0){ + + static GLuint framebuffer_handle; + framebuffer_handle=0; + glGenFramebuffersEXT(1, &framebuffer_handle); + glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_handle); + hardware_img->dest_context_handle=framebuffer_handle; + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hardware_img->texture_handle, 0); + + //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + //glClear(GL_COLOR_BUFFER_BIT); + glColor4f(1.f, 1.f, 1.f, 1.f); + + set_render_source(INVALID_HARDWARE_HANDLE); + + }else{ + glBindFramebufferEXT(GL_FRAMEBUFFER, hardware_img->dest_context_handle); + } + render_state.dest=&hardware_img->dest_state; +} +render_state.dest_handle=new_handle; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + void hardware_img_put(int32 dst_x1,int32 dst_y1,int32 dst_x2,int32 dst_y2, + int32 src_img,int32 dst_img, + int32 src_x1,int32 src_y1,int32 src_x2,int32 src_y2, + int32 use_alpha, + int32 smooth + ){ + + if (dst_img<0) dst_img=0;//both layers render to the primary context + + //ensure dst_x1/y1 represent top-left co-ordinate of destination + static int32 swap_tmp; + if (dst_x2x1; + dst_y1=rect->y1; + dst_x2=rect->x2; + dst_y2=rect->y2; + } + + set_render_source(src_img); + + static hardware_img_struct* src_hardware_img; + static int32 src_h,src_w; + src_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,src_img); + src_h=src_hardware_img->h; + src_w=src_hardware_img->w; + + + if (smooth){ + set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__SMOOTH); + }else{ + set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__DONT_SMOOTH); + } + + if (use_alpha){ + set_alpha(ALPHA_MODE__BLEND); + }else{ + set_alpha(ALPHA_MODE__DONT_BLEND); + } + + set_depthbuffer(DEPTHBUFFER_MODE__OFF); + set_cull_mode(CULL_MODE__NONE); + + set_texture_wrap(TEXTURE_WRAP_MODE__DONT_WRAP); + + + + //adjust for render (x2 & y2 need to be one greater than the destination offset) + dst_x2++; dst_y2++; + +if (src_hardware_img->source_state.PO2_fix){ + src_w=src_hardware_img->PO2_w; + src_h=src_hardware_img->PO2_h; +} + + //calc source texture co-ordinates + static float x1f,y1f,x2f,y2f; + if (src_x1<=src_x2){ + x1f=((float)src_x1+0.01f)/(float)src_w; + x2f=((float)src_x2+0.99f)/(float)src_w; + }else{ + x2f=((float)src_x2+0.01f)/(float)src_w; + x1f=((float)src_x1+0.99f)/(float)src_w; + } + if (src_y1<=src_y2){ + y1f=((float)src_y1+0.01f)/(float)src_h; + y2f=((float)src_y2+0.99f)/(float)src_h; + }else{ + y2f=((float)src_y2+0.01f)/(float)src_h; + y1f=((float)src_y1+0.99f)/(float)src_h; + } + + //expand buffers if necessary + if ((hardware_buffer_vertices_count+18)>hardware_buffer_vertices_max){ + hardware_buffer_vertices_max=hardware_buffer_vertices_max*2+18; + hardware_buffer_vertices=(float*)realloc(hardware_buffer_vertices,hardware_buffer_vertices_max*sizeof(float)); + } + if ((hardware_buffer_texcoords_count+12)>hardware_buffer_texcoords_max){ + hardware_buffer_texcoords_max=hardware_buffer_texcoords_max*2+12; + hardware_buffer_texcoords=(float*)realloc(hardware_buffer_texcoords,hardware_buffer_texcoords_max*sizeof(float)); + } + hardware_buffer_vertices_int=(int32*)hardware_buffer_vertices; + + //clockwise + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; + + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; + + //hardware_buffer_flush(); //uncomment for debugging only + + } + + + + + + void hardware_img_tri2d(float dst_x1,float dst_y1,float dst_x2,float dst_y2,float dst_x3,float dst_y3, + int32 src_img,int32 dst_img, + float src_x1,float src_y1,float src_x2,float src_y2,float src_x3,float src_y3, + int32 use_alpha, + int32 smooth + ){ + + if (dst_img<0) dst_img=0;//both layers render to the primary context + + set_render_dest(dst_img); + set_view(VIEW_MODE__2D); + + if (dst_img){ + static hardware_img_struct* dst_hardware_img; + dst_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,dst_img); + +static int32 dst_w,dst_h; +dst_w=dst_hardware_img->w; +dst_h=dst_hardware_img->h; +//SEAMLESS adjustments: +//reduce texture co-ordinates (maintaining top-left) +//(todo) +//NON-SEAMLESS adjustments: +//Extend rhs/bottom row to fill extra pixel space +//calculate extents +int32 rx1; +int32 rx2; +rx1=dst_x1; +if (dst_x2rx2){ +rx2=dst_x2; +} +if (dst_x3>rx2){ +rx2=dst_x3; +} +float xr;//the multiplier for where we should be (1=no change) +if (rx1==rx2){ +xr=1.0f; +}else{ +xr=((float)rx2-(float)rx1+1.0)/((float)rx2-(float)rx1); +} +int32 ry1; +int32 ry2; +ry1=dst_y1; +if (dst_y2ry2){ +ry2=dst_y2; +} +if (dst_y3>ry2){ +ry2=dst_y3; +} +float yr;//the multiplier for where we should be (1=no change) +if (ry1==ry2){ +yr=1.0f; +}else{ +yr=((float)ry2-(float)ry1+1.0f)/((float)ry2-(float)ry1); +} +//apply multipliers so right-most and bottom-most rows will be filled +static int32 basex; +basex=rx1; +dst_x1=qbr_float_to_long( +((float)(dst_x1-rx1))*xr+(float)basex +); +dst_x2=qbr_float_to_long( +((float)(dst_x2-rx1))*xr+(float)basex +); +dst_x3=qbr_float_to_long( +((float)(dst_x3-rx1))*xr+(float)basex +); +static int32 basey; +basey=ry1; +dst_y1=qbr_float_to_long( +((float)(dst_y1-ry1))*yr+(float)basey +); +dst_y2=qbr_float_to_long( +((float)(dst_y2-ry1))*yr+(float)basey +); +dst_y3=qbr_float_to_long( +((float)(dst_y3-ry1))*yr+(float)basey +); + + }else{ //dest is 0 + +static int32 dst_w,dst_h; +dst_w=environment__window_width; +dst_h=environment__window_height; +//SEAMLESS adjustments: +//reduce texture co-ordinates (maintaining top-left) +//(todo) +//NON-SEAMLESS adjustments: +//Extend rhs/bottom row to fill extra pixel space +//calculate extents +int32 rx1; +int32 rx2; +rx1=dst_x1; +if (dst_x2rx2){ +rx2=dst_x2; +} +if (dst_x3>rx2){ +rx2=dst_x3; +} +float xr;//the multiplier for where we should be (1=no change) +if (rx1==rx2){ +xr=1.0f; +}else{ +xr=((float)rx2-(float)rx1+1.0)/((float)rx2-(float)rx1); +} +int32 ry1; +int32 ry2; +ry1=dst_y1; +if (dst_y2ry2){ +ry2=dst_y2; +} +if (dst_y3>ry2){ +ry2=dst_y3; +} +float yr;//the multiplier for where we should be (1=no change) +if (ry1==ry2){ +yr=1.0f; +}else{ +yr=((float)ry2-(float)ry1+1.0f)/((float)ry2-(float)ry1); +} +//apply multipliers so right-most and bottom-most rows will be filled +static int32 basex; +basex= +qbr_float_to_long( +((float)(rx1))*environment_2d__screen_x_scale+(float)environment_2d__screen_x1 +); +dst_x1= +basex+ +qbr_float_to_long( +((float)(dst_x1-rx1))*environment_2d__screen_x_scale*xr +); +dst_x2= +basex+ +qbr_float_to_long( +((float)(dst_x2-rx1))*environment_2d__screen_x_scale*xr +); +dst_x3= +basex+ +qbr_float_to_long( +((float)(dst_x3-rx1))*environment_2d__screen_x_scale*xr +); +static int32 basey; +basey= +qbr_float_to_long( +((float)(ry1))*environment_2d__screen_y_scale+(float)environment_2d__screen_y1 +); +dst_y1= +basey+ +qbr_float_to_long( +((float)(dst_y1-ry1))*environment_2d__screen_y_scale*yr +); +dst_y2= +basey+ +qbr_float_to_long( +((float)(dst_y2-ry1))*environment_2d__screen_y_scale*yr +); +dst_y3= +basey+ +qbr_float_to_long( +((float)(dst_y3-ry1))*environment_2d__screen_y_scale*yr +); + + } + + set_render_source(src_img); + + static hardware_img_struct* src_hardware_img; + static int32 src_h,src_w; + src_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,src_img); + src_h=src_hardware_img->h; + src_w=src_hardware_img->w; + + if (smooth==0){ + set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__DONT_SMOOTH); + } + if (smooth==1){ + set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__SMOOTH); + } + if (smooth==2){ + set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__DONT_SMOOTH); + } + if (smooth==3){ + set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__SMOOTH); + } + + set_texture_wrap(TEXTURE_WRAP_MODE__WRAP); + + if (use_alpha){ + set_alpha(ALPHA_MODE__BLEND); + }else{ + set_alpha(ALPHA_MODE__DONT_BLEND); + } + + set_depthbuffer(DEPTHBUFFER_MODE__OFF); + set_cull_mode(CULL_MODE__NONE); + +if (src_hardware_img->source_state.PO2_fix){ + src_w=src_hardware_img->PO2_w; + src_h=src_hardware_img->PO2_h; +} + + //calc source texture co-ordinates + static float x1f,y1f,x2f,y2f,x3f,y3f; + x1f=((float)src_x1+0.5f)/(float)src_w; + x2f=((float)src_x2+0.5f)/(float)src_w; + x3f=((float)src_x3+0.5f)/(float)src_w; + y1f=((float)src_y1+0.5f)/(float)src_h; + y2f=((float)src_y2+0.5f)/(float)src_h; + y3f=((float)src_y3+0.5f)/(float)src_h; + + + //expand buffers if necessary + if ((hardware_buffer_vertices_count+9)>hardware_buffer_vertices_max){ + hardware_buffer_vertices_max=hardware_buffer_vertices_max*2+9; + hardware_buffer_vertices=(float*)realloc(hardware_buffer_vertices,hardware_buffer_vertices_max*sizeof(float)); + } + if ((hardware_buffer_texcoords_count+6)>hardware_buffer_texcoords_max){ + hardware_buffer_texcoords_max=hardware_buffer_texcoords_max*2+6; + hardware_buffer_texcoords=(float*)realloc(hardware_buffer_texcoords,hardware_buffer_texcoords_max*sizeof(float)); + } + hardware_buffer_vertices_int=(int32*)hardware_buffer_vertices; + + + + //clockwise + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y1; + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y2; + hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_x3; hardware_buffer_vertices_int[hardware_buffer_vertices_count++]=dst_y3; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x3f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y3f; + + //hardware_buffer_flush(); //uncomment for debugging only + + } + +void clear_depthbuffer(int32 dst_img){ + hardware_buffer_flush(); + if (dst_img<0) dst_img=0;//both layers render to the primary context + set_render_dest(dst_img); + if (dst_img>0){ + hardware_img_requires_depthbuffer((hardware_img_struct*)list_get(hardware_img_handles,dst_img)); + } + glClear(GL_DEPTH_BUFFER_BIT); +} + + void hardware_img_tri3d(float dst_x1,float dst_y1,float dst_z1,float dst_x2,float dst_y2,float dst_z2,float dst_x3,float dst_y3,float dst_z3, + int32 src_img,int32 dst_img, + float src_x1,float src_y1,float src_x2,float src_y2,float src_x3,float src_y3, + int32 use_alpha, + int32 smooth, + int32 cull_mode, + int32 depthbuffer_mode + ){ + + if (dst_img<0) dst_img=0;//both layers render to the primary context + + set_render_dest(dst_img); + set_view(VIEW_MODE__3D); + + if (dst_img){ + static hardware_img_struct* dst_hardware_img; + dst_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,dst_img); + hardware_img_requires_depthbuffer(dst_hardware_img); + }else{ //dest is 0 + } + + set_render_source(src_img); + + static hardware_img_struct* src_hardware_img; + static int32 src_h,src_w; + src_hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,src_img); + src_h=src_hardware_img->h; + src_w=src_hardware_img->w; + + if (smooth==0){ + set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__DONT_SMOOTH); + } + if (smooth==1){ + set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__SMOOTH); + } + if (smooth==2){ + set_smooth(SMOOTH_MODE__SMOOTH,SMOOTH_MODE__DONT_SMOOTH); + } + if (smooth==3){ + set_smooth(SMOOTH_MODE__DONT_SMOOTH,SMOOTH_MODE__SMOOTH); + } + + set_texture_wrap(TEXTURE_WRAP_MODE__WRAP); + + if (use_alpha){ + set_alpha(ALPHA_MODE__BLEND); + }else{ + set_alpha(ALPHA_MODE__DONT_BLEND); + } + + set_depthbuffer(depthbuffer_mode); + + //on frame buffers the 3D perspective is flipped vertically reversing the cull direction + if (dst_img>0){ + if (cull_mode==CULL_MODE__CLOCKWISE_ONLY){ + cull_mode=CULL_MODE__ANTICLOCKWISE_ONLY; + }else{ + if (cull_mode==CULL_MODE__ANTICLOCKWISE_ONLY) cull_mode=CULL_MODE__CLOCKWISE_ONLY; + } + } + + set_cull_mode(cull_mode); + +if (src_hardware_img->source_state.PO2_fix){ + src_w=src_hardware_img->PO2_w; + src_h=src_hardware_img->PO2_h; +} + + //calc source texture co-ordinates + static float x1f,y1f,x2f,y2f,x3f,y3f; + x1f=((float)src_x1+0.5f)/(float)src_w; + x2f=((float)src_x2+0.5f)/(float)src_w; + x3f=((float)src_x3+0.5f)/(float)src_w; + y1f=((float)src_y1+0.5f)/(float)src_h; + y2f=((float)src_y2+0.5f)/(float)src_h; + y3f=((float)src_y3+0.5f)/(float)src_h; + + //expand buffers if necessary + if ((hardware_buffer_vertices_count+9)>hardware_buffer_vertices_max){ + hardware_buffer_vertices_max=hardware_buffer_vertices_max*2+9; + hardware_buffer_vertices=(float*)realloc(hardware_buffer_vertices,hardware_buffer_vertices_max*sizeof(float)); + } + if ((hardware_buffer_texcoords_count+6)>hardware_buffer_texcoords_max){ + hardware_buffer_texcoords_max=hardware_buffer_texcoords_max*2+6; + hardware_buffer_texcoords=(float*)realloc(hardware_buffer_texcoords,hardware_buffer_texcoords_max*sizeof(float)); + } + + hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_x1; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_y1; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_z1; + hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_x2; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_y2; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_z2; + hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_x3; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_y3; hardware_buffer_vertices[hardware_buffer_vertices_count++]=dst_z3; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x1f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y1f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x2f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y2f; + hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=x3f; hardware_buffer_texcoords[hardware_buffer_texcoords_count++]=y3f; + //hardware_buffer_flush(); //uncomment for debugging only + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + static int32 software_screen_hardware_frame=0; + + static int32 in_GLUT_DISPLAY_REQUEST=0; + + void GLUT_DISPLAY_REQUEST(){ + + if (in_GLUT_DISPLAY_REQUEST){ + return; + } + in_GLUT_DISPLAY_REQUEST=1; + + //general use variables + static int32 i,i2,i3; + static int32 x,y,x2,y2; + + //determine which software frame to display + static int32 last_i;//the last software frame displayed + last_i=-1; + for (i2=0;i2<=2;i2++){ + if (display_frame[i2].state==DISPLAY_FRAME_STATE__DISPLAYING){ + last_i=i2; + } + } + i=-1; + static int64 highest_order; + highest_order=0; + if (last_i!=-1) highest_order=display_frame[last_i].order;//avoid any frames below the current one + for (i2=0;i2<=2;i2++){ + if (display_frame[i2].state==DISPLAY_FRAME_STATE__READY&&display_frame[i2].order>highest_order){ + highest_order=display_frame[i2].order; + i=i2; + } + } + if (i==-1) i=last_i; + if (i==-1){ + in_GLUT_DISPLAY_REQUEST=0; + return;//no frames exist yet, so screen size cannot be determined, therefore no action possible + } + if (i!=last_i){ + for (i2=0; i2<=2;i2++){ + if (display_frame[i2].order1) use_alpha=1; + + //put the software screen + hardware_img_put(0,0,environment_2d__screen_width-1,environment_2d__screen_height-1, + software_screen_hardware_frame, 0, + 0,0,f1->w-1,f1->h-1, + use_alpha,environment_2d__screen_smooth); + hardware_buffer_flush(); + }//level==displayorder_screen + + + if (level==displayorder_hardware||level==displayorder_hardware1){ + + static int32 dst; + dst=0; if (level==displayorder_hardware1) dst=-1; + + static int32 command; + command=0; + + if (first_hardware_layer_rendered==0){ + + if (first_hardware_command){ + + if (last_hardware_command_rendered){ + if (rerender_prev_hardware_frame){ + command=last_hardware_command_rendered; + }else{ + hardware_graphics_command_struct* last_hgc=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,last_hardware_command_rendered); + if (last_hgc==NULL) alert("Rendering: Last HGC is NULL!"); + command=last_hgc->next_command; + } + }else{ + command=first_hardware_command; + } + + //process/skip pending hardware puts before this frame's order value + while (command){ + hardware_graphics_command_struct* hgc=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,command); + if (hgc->ordercommand==HARDWARE_GRAPHICS_COMMAND__FREEIMAGE){ + free_hardware_img(hgc->src_img); + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__PUTIMAGE){ + if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required + hardware_img_put(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2, + hgc->src_img, hgc->dst_img, + hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2, + hgc->use_alpha,hgc->smooth); + } + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE){ + if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required + hardware_img_tri2d(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2,hgc->dst_x3,hgc->dst_y3, + hgc->src_img, hgc->dst_img, + hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, + hgc->use_alpha,hgc->smooth); + } + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE3D){ + if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required + hardware_img_tri3d(hgc->dst_x1,hgc->dst_y1,hgc->dst_z1,hgc->dst_x2,hgc->dst_y2,hgc->dst_z2,hgc->dst_x3,hgc->dst_y3,hgc->dst_z3, + hgc->src_img, hgc->dst_img, + hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, + hgc->use_alpha,hgc->smooth,hgc->cull_mode,hgc->depthbuffer_mode); + } + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__CLEAR_DEPTHBUFFER){ + if (hgc->dst_img>0){ //note: rendering to the old default surface is pointless, but renders onto maintained hardware images are still required + clear_depthbuffer(hgc->dst_img); + } + } + + last_hardware_command_rendered=command; + if (next_hardware_command_to_remove==0) next_hardware_command_to_remove=command; + command=hgc->next_command; + hgc->remove=1; + }else{ + goto found_command_from_current_order; + } + } + found_command_from_current_order:; + + }//first_hardware_command + + + first_hardware_layer_command=command; + }else{ + command=first_hardware_layer_command; + } + + //process pending hardware puts for this frame's order value + while (command){ + hardware_graphics_command_struct* hgc=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,command); + if (hgc==NULL){ + + hardware_graphics_command_struct* hgcx=(hardware_graphics_command_struct*)list_get(hardware_graphics_command_handles,next_hardware_command_to_remove); + alert(order); + alert(hgcx->order); + alert(command); + alert ("Renderer: Command does not exist."); + } + if (hgc->order==order){ + if (first_command_prev_order==0) first_command_prev_order=command; + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__FREEIMAGE&&rerender_prev_hardware_frame==0&&first_hardware_layer_rendered==0){ + free_hardware_img(hgc->src_img); + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__PUTIMAGE){ + if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ + if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ + hardware_img_put(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2, + hgc->src_img, hgc->dst_img, + hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2, + hgc->use_alpha,hgc->smooth); + } + } + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE){ + if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ + if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ + hardware_img_tri2d(hgc->dst_x1,hgc->dst_y1,hgc->dst_x2,hgc->dst_y2,hgc->dst_x3,hgc->dst_y3, + hgc->src_img, hgc->dst_img, + hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, + hgc->use_alpha,hgc->smooth); + } + } + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__MAPTRIANGLE3D){ + if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ + if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ + hardware_img_tri3d(hgc->dst_x1,hgc->dst_y1,hgc->dst_z1,hgc->dst_x2,hgc->dst_y2,hgc->dst_z2,hgc->dst_x3,hgc->dst_y3,hgc->dst_z3, + hgc->src_img, hgc->dst_img, + hgc->src_x1,hgc->src_y1,hgc->src_x2,hgc->src_y2,hgc->src_x3,hgc->src_y3, + hgc->use_alpha,hgc->smooth,hgc->cull_mode,hgc->depthbuffer_mode); + } + } + } + + if (hgc->command==HARDWARE_GRAPHICS_COMMAND__CLEAR_DEPTHBUFFER){ + if (rerender_prev_hardware_frame==0||hgc->dst_img<=0){ + if ((hgc->dst_img>0&&first_hardware_layer_rendered==0)||hgc->dst_img==dst){ + clear_depthbuffer(hgc->dst_img); + } + } + } + + last_hardware_command_rendered=command; + if (next_hardware_command_to_remove==0) next_hardware_command_to_remove=command;//!!!! should be prev to this command + command=hgc->next_command; + hgc->remove=1; + }else{ + goto finished_all_commands_for_current_frame; + } + + + } + finished_all_commands_for_current_frame:; + + first_hardware_layer_rendered=1; + + + + hardware_buffer_flush(); + }//level==displayorder_hardware||level==displayorder_hardware1 + + + if (level==5){ + + if (environment_2d__letterbox){ + + //create a black texture (if not yet created) + static uint32 black_pixel=0x00000000; + static int32 black_texture=0; + if (black_texture==0){ + black_texture=new_hardware_img(1,1,&black_pixel,NULL); + } + + if (environment_2d__letterbox==1){ + //vertical stripes + hardware_img_put(((float)-environment_2d__screen_x1)/environment_2d__screen_x_scale-1.0f,0,-1,environment_2d__screen_height-1, + black_texture, 0, + 0,0,0,0, + 0,0); + hardware_img_put(environment_2d__screen_width,0,(((float)-environment_2d__screen_x1)+(float)environment__window_width-1.0f)/environment_2d__screen_x_scale+1.0f,environment_2d__screen_height-1, + black_texture, 0, + 0,0,0,0, + 0,0); + }else{ + //horizontal stripes + hardware_img_put(0,((float)-environment_2d__screen_y1)/environment_2d__screen_y_scale-1.0f,environment_2d__screen_width-1,-1, + black_texture, 0, + 0,0,0,0, + 0,0); + hardware_img_put(0,environment_2d__screen_height,environment_2d__screen_width-1,(((float)-environment_2d__screen_y1)+(float)environment__window_height-1.0f)/environment_2d__screen_y_scale+1.0f, + black_texture, 0, + 0,0,0,0, + 0,0); + } + hardware_buffer_flush(); + }//letterbox + + }//level==5 + + + }//level!=0 + }//level loop + + last_rendered_hardware_display_frame_order=last_hardware_display_frame_order; + + + + if (suspend_program){ //Otherwise skipped SUB__GL content becomes "invisible" + //... + }else{ + glutSwapBuffers(); + } + + in_GLUT_DISPLAY_REQUEST=0; + + }//GLUT_DISPLAY_REQUEST + + + + + + void GLUT_MouseButton_Up(int glut_button,int x,int y){ +#ifdef QB64_GLUT + + int32 i; + int32 button; + button=1;//default + if (glut_button==GLUT_LEFT_BUTTON) button=1; + if (glut_button==GLUT_RIGHT_BUTTON) button=3; + if (glut_button==GLUT_MIDDLE_BUTTON) button=2; + if (glut_button==4) button=4; + if (glut_button==5) button=5; + i=(last_mouse_message+1)&65535; + if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message + mouse_messages[i].movementx=0; + mouse_messages[i].movementy=0; + mouse_messages[i].x=x; + mouse_messages[i].y=y; + mouse_messages[i].buttons=mouse_messages[last_mouse_message].buttons; + if (mouse_messages[i].buttons&(1<<(button-1))) mouse_messages[i].buttons^=(1<<(button-1)); + last_mouse_message=i; + if (device_last){//core devices required? + if ((button>=1)&&(button<=3)){ + button--; + static device_struct *d; + d=&devices[2];//mouse + static uint8 *cp,*cp2; + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + *(d->events+(d->queued_events*d->event_size)+button)=0; + d->queued_events++; + }//valid range + }//core devices required + +#endif + } + + void GLUT_MouseButton_Down(int glut_button,int x,int y){ +#ifdef QB64_GLUT + + int32 i; + int32 button; + button=1;//default + if (glut_button==GLUT_LEFT_BUTTON) button=1; + if (glut_button==GLUT_RIGHT_BUTTON) button=3; + if (glut_button==GLUT_MIDDLE_BUTTON) button=2; + if (glut_button==4) button=4; + if (glut_button==5) button=5; + i=(last_mouse_message+1)&65535; + if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message + mouse_messages[i].movementx=0; + mouse_messages[i].movementy=0; + mouse_messages[i].x=x; + mouse_messages[i].y=y; + mouse_messages[i].buttons=mouse_messages[last_mouse_message].buttons; + mouse_messages[i].buttons|=(1<<(button-1)); + last_mouse_message=i; + if (device_last){//core devices required? + if ((button>=1)&&(button<=3)){ + button--; + static device_struct *d; + d=&devices[2];//mouse + static uint8 *cp,*cp2; + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + *(d->events+(d->queued_events*d->event_size)+button)=1; + d->queued_events++; + //1-3 + }else{ + //not 1-3 + //mouse wheel? + if ((button>=4)&&(button<=5)){ + static float f; + if (button==4) f=-1; else f=1; + static device_struct *d; + d=&devices[2];//mouse + static uint8 *cp,*cp2; + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+(3-1)*4)=f; + d->queued_events++; + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+(3-1)*4)=0; + d->queued_events++; + }//4-5 + }//not 1-3 + }//core devices required +#endif + } + + void GLUT_MOUSE_FUNC(int glut_button,int state,int x,int y){ +#ifdef QB64_GLUT + if (state==GLUT_DOWN) GLUT_MouseButton_Down(glut_button,x,y); + if (state==GLUT_UP) GLUT_MouseButton_Up(glut_button,x,y); +#endif + } + + void GLUT_MOTION_FUNC(int x, int y){ + + static int32 i,last_i; + static int32 xrel=0,yrel=0; + //message #1 + last_i=last_mouse_message; + i=(last_mouse_message+1)&65535; + if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message + mouse_messages[i].x=x; + mouse_messages[i].y=y; + if (mouseinput_ignoremovement){ + mouseinput_ignoremovement--; + mouse_messages[i].movementx=0; + mouse_messages[i].movementy=0; + }else{ + mouse_messages[i].movementx=xrel; + mouse_messages[i].movementy=yrel; + } + mouse_messages[i].buttons=mouse_messages[last_i].buttons; + last_mouse_message=i; + //message #2 (clears movement values to avoid confusion) + last_i=last_mouse_message; + i=(last_mouse_message+1)&65535; + if (i==current_mouse_message) current_mouse_message=(current_mouse_message+1)&65535;//if buffer full, skip oldest message + mouse_messages[i].x=x; + mouse_messages[i].y=y; + mouse_messages[i].movementx=0; + mouse_messages[i].movementy=0; + mouse_messages[i].buttons=mouse_messages[last_i].buttons; + last_mouse_message=i; + if (device_last){//core devices required? + if (!device_mouse_relative){ + static device_struct *d; + d=&devices[2];//mouse + static uint8 *cp,*cp2; + + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + static float fx,fy; + static int32 z; + fx=x; + fx-=x_offset; + z=x_monitor-x_offset*2; + if (fx<0) fx=0; + if (fx>=z) fx=z-1; + fx=fx/(float)(z-1);//0 to 1 + fx*=2.0;//0 to 2 + fx-=1.0;//-1 to 1 + fy=y; + fy-=y_offset; + z=y_monitor-y_offset*2; + if (fy<0) fy=0; + if (fy>=z) fy=z-1; + fy=fy/(float)(z-1);//0 to 1 + fy*=2.0;//0 to 2 + fy-=1.0;//-1 to 1 + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton)=fx; + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+4)=fy; + d->queued_events++; + }else{ + static device_struct *d; + d=&devices[2];//mouse + static uint8 *cp,*cp2; + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + static float fx,fy; + static int32 z; + fx=xrel; + fy=yrel; + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4)=fx; + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+4)=fy; + d->queued_events++; + if (d->queued_events==d->max_events){//expand/shift event buffer + if (d->max_events>=QUEUED_EVENTS_LIMIT){ + //discard base message + memmove(d->events,d->events+d->event_size,(d->queued_events-1)*d->event_size); + d->queued_events--; + }else{ + cp=(uint8*)calloc(d->max_events*2,d->event_size); + memcpy(cp,d->events,d->queued_events*d->event_size);//copy existing events + cp2=d->events; + d->events=cp; + free(cp2); + d->max_events*=2; + } + } + memmove(d->events+d->queued_events*d->event_size,d->events+(d->queued_events-1)*d->event_size,d->event_size);//duplicate last event + *(int64*)(d->events+(d->queued_events*d->event_size)+(d->event_size-8))=device_event_index++;//store global event index + //make required changes + fx=0; + fy=0; + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4)=fx; + *(float*)(d->events+(d->queued_events*d->event_size)+d->lastbutton+d->lastaxis*4+4)=fy; + d->queued_events++; + } + }//core devices required + } + + void GLUT_PASSIVEMOTION_FUNC(int x, int y){ + GLUT_MOTION_FUNC(x,y); + } + + + void GLUT_MOUSEWHEEL_FUNC(int wheel, int direction, int x, int y){ +#ifdef QB64_GLUT + //Note: freeglut specific, limited documentation existed so the following research was done: + // qbs_print(qbs_str(wheel),NULL); <-- was always 0 [could 1 indicate horizontal wheel?] + // qbs_print(qbs_str(direction),NULL); <-- 1(up) or -1(down) + // qbs_print(qbs_str(x),NULL); <--mouse x,y co-ordinates + // qbs_print(qbs_str(y),1); < + if (direction>0){GLUT_MouseButton_Down(4,x,y); GLUT_MouseButton_Up(4,x,y);} + if (direction<0){GLUT_MouseButton_Down(5,x,y); GLUT_MouseButton_Up(5,x,y);} +#endif + } + + + + + + + + + + +#endif diff --git a/internal/c/libqb/gui.h b/internal/c/libqb/gui.h new file mode 100644 index 000000000..a5830297b --- /dev/null +++ b/internal/c/libqb/gui.h @@ -0,0 +1,278 @@ +#ifndef QB64_GUI //begin stubs + +//STUB: simulate generating a hardware surface +int32 new_hardware_img(int32 x, int32 y, uint32 *pixels, int32 flags){ + //create hardware img + int32 handle; + hardware_img_struct* hardware_img; + handle=list_add(hardware_img_handles); + hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle); + hardware_img->w=x; + hardware_img->h=y; + hardware_img->dest_context_handle=0; + hardware_img->depthbuffer_handle=0; + hardware_img->pending_commands=0; + hardware_img->remove=0; + hardware_img->alpha_disabled=0; + hardware_img->depthbuffer_mode=DEPTHBUFFER_MODE__ON; + hardware_img->valid=1; + hardware_img->source_state.PO2_fix=PO2_FIX__OFF; + hardware_img->source_state.texture_wrap=TEXTURE_WRAP_MODE__UNKNOWN; + hardware_img->source_state.smooth_stretched=SMOOTH_MODE__UNKNOWN; + hardware_img->source_state.smooth_shrunk=SMOOTH_MODE__UNKNOWN; + if (flags&NEW_HARDWARE_IMG__BUFFER_CONTENT){ + hardware_img->texture_handle=0; + if (flags&NEW_HARDWARE_IMG__DUPLICATE_PROVIDED_BUFFER){ + hardware_img->software_pixel_buffer=NULL; + }else{ + free(pixels);//the buffer was meant to be consumed, so we just free it immediately + hardware_img->software_pixel_buffer=NULL; + } + } + return handle; +} + + + + + + + + + + + + + + + +#else //end stubs + + + +int32 force_NPO2_fix=0;//This should only be set to 1 for debugging QB64 + +uint32 *NPO2_buffer=(uint32*)malloc(4); +int32 NPO2_buffer_size_in_pixels=1; + +uint32 *NPO2_texture_generate(int32 *px, int32 *py, uint32 *pixels){ +int32 ox=*px; +int32 oy=*py; +int32 nx=1; +int32 ny=1; + +//assume not negative & not 0 +while ((ox&1)==0){ + ox>>=1; + nx<<=1; +} +if (ox!=1){//x is not a power of 2 + while (ox!=0){ + ox>>=1; + nx<<=1; + } + nx<<1; +} +while ((oy&1)==0){ + oy>>=1; + ny<<=1; +} +if (oy!=1){//y is not a power of 2 + while (oy!=0){ + oy>>=1; + ny<<=1; + } + ny<<1; +} + +//reset original values +ox=*px; +oy=*py; + +if (nx==ox&&ny==oy){ //no action required + return pixels; +} + +int32 size_in_pixels=nx*ny; +if (size_in_pixels>NPO2_buffer_size_in_pixels){ + NPO2_buffer=(uint32*)realloc(NPO2_buffer,size_in_pixels*4); + NPO2_buffer_size_in_pixels=size_in_pixels; +} + +//copy source NPO2 rectangle into destination PO2 rectangle +if (nx==ox){ //can copy as a single block + memcpy(NPO2_buffer,pixels,ox*oy*4); +}else{ + uint32 *dst_pixel_offset=NPO2_buffer; + uint32 *src_pixel_offset=pixels; + while (oy--){ + memcpy(dst_pixel_offset,src_pixel_offset,ox*4); + dst_pixel_offset+=nx; + src_pixel_offset+=ox; + } + oy=*py; +} + +//tidy edges - extend the right-most column and bottom-most row to avoid pixel/color bleeding +//rhs column +if (ox!=nx){ +for (int y=0;yw=x; + hardware_img->h=y; + hardware_img->dest_context_handle=0; + hardware_img->depthbuffer_handle=0; + hardware_img->pending_commands=0; + hardware_img->remove=0; + hardware_img->alpha_disabled=0; + hardware_img->depthbuffer_mode=DEPTHBUFFER_MODE__ON; + hardware_img->valid=1; + hardware_img->source_state.PO2_fix=PO2_FIX__OFF; + hardware_img->source_state.texture_wrap=TEXTURE_WRAP_MODE__UNKNOWN; + hardware_img->source_state.smooth_stretched=SMOOTH_MODE__UNKNOWN; + hardware_img->source_state.smooth_shrunk=SMOOTH_MODE__UNKNOWN; + + if (flags&NEW_HARDWARE_IMG__BUFFER_CONTENT){ + hardware_img->texture_handle=0; + if (flags&NEW_HARDWARE_IMG__DUPLICATE_PROVIDED_BUFFER){ + hardware_img->software_pixel_buffer=(uint32*)malloc(x*y*4); + memcpy(hardware_img->software_pixel_buffer,pixels,x*y*4); + }else{ + hardware_img->software_pixel_buffer=pixels; + } + }else{ + hardware_img->software_pixel_buffer=NULL; + hardware_img->texture_handle=new_texture_handle(); + glBindTexture (GL_TEXTURE_2D, hardware_img->texture_handle); + //non-power of 2 dimensions fallback support + static int glerrorcode; + glerrorcode=glGetError();//clear any previous errors + if (force_NPO2_fix==0) glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); + glerrorcode=glGetError(); + if (glerrorcode!=0||force_NPO2_fix==1){ + int32 nx=x,ny=y; + uint32 *npixels=NPO2_texture_generate(&nx,&ny,pixels); + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_BGRA, GL_UNSIGNED_BYTE,npixels); + hardware_img->source_state.PO2_fix=PO2_FIX__EXPANDED; + hardware_img->PO2_w=nx; + hardware_img->PO2_h=ny; + glerrorcode=glGetError(); + if (glerrorcode){ + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, x, y, GL_BGRA, GL_UNSIGNED_BYTE, pixels ); + glerrorcode=glGetError(); + if (glerrorcode){ + alert("gluBuild2DMipmaps failed"); + alert(glerrorcode); + } + hardware_img->source_state.PO2_fix=PO2_FIX__MIPMAPPED; + hardware_img->PO2_w=x; + hardware_img->PO2_h=y; + } + } + set_render_source(INVALID_HARDWARE_HANDLE); + } + return handle; +} + +void hardware_img_buffer_to_texture(int32 handle){ + static hardware_img_struct* hardware_img; + hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle); + if (hardware_img->texture_handle==0){ + hardware_img->texture_handle=new_texture_handle(); + glBindTexture (GL_TEXTURE_2D, hardware_img->texture_handle); + //non-power of 2 dimensions fallback support + static int glerrorcode; + glerrorcode=glGetError();//clear any previous errors + if (force_NPO2_fix==0) glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, hardware_img->w, hardware_img->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, hardware_img->software_pixel_buffer); + glerrorcode=glGetError(); + if (glerrorcode!=0||force_NPO2_fix==1){ + hardware_img->source_state.PO2_fix=PO2_FIX__EXPANDED; + int32 x=hardware_img->w; + int32 y=hardware_img->h; + uint32 *pixels=NPO2_texture_generate(&x,&y,hardware_img->software_pixel_buffer); + hardware_img->PO2_w=x; + hardware_img->PO2_h=y; + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_BGRA, GL_UNSIGNED_BYTE,pixels); + glerrorcode=glGetError(); + if (glerrorcode){ + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, hardware_img->w, hardware_img->h, GL_BGRA, GL_UNSIGNED_BYTE, hardware_img->software_pixel_buffer); + glerrorcode=glGetError(); + if (glerrorcode){ + alert("gluBuild2DMipmaps failed"); + alert(glerrorcode); + } + hardware_img->source_state.PO2_fix=PO2_FIX__MIPMAPPED; + hardware_img->PO2_w=hardware_img->w; + hardware_img->PO2_h=hardware_img->h; + } + } + free(hardware_img->software_pixel_buffer); + set_render_source(INVALID_HARDWARE_HANDLE); + } +} + +void hardware_img_requires_depthbuffer(hardware_img_struct* hardware_img){ +if (hardware_img->depthbuffer_handle==0){ + //inspiration... http://www.opengl.org/wiki/Framebuffer_Object_Examples#Color_texture.2C_Depth_texture + static GLuint depth_tex; + glGenTextures(1, &depth_tex); + glBindTexture(GL_TEXTURE_2D, depth_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + //NULL means reserve texture memory, but texels are undefined + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, hardware_img->w, hardware_img->h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0/*mipmap level*/); + glClear(GL_DEPTH_BUFFER_BIT); + hardware_img->depthbuffer_handle=depth_tex; + set_render_source(INVALID_HARDWARE_HANDLE); +} +} + + +#endif diff --git a/internal/c/libqb/printer.cpp b/internal/c/libqb/printer.cpp new file mode 100644 index 000000000..058b38609 --- /dev/null +++ b/internal/c/libqb/printer.cpp @@ -0,0 +1,80 @@ +#ifndef DEPENDENCY_PRINTER + + //stubs + void sub__printimage(int32 i){ + return; + } + +#else + + void sub__printimage(int32 i){ + + #ifdef QB64_WINDOWS + + static LPSTR szPrinterName=NULL; + DWORD dwNameLen; + HDC dc; + DOCINFO di; + uint32 w,h; + int32 x,y; + int32 i2; + BITMAPFILEHEADER bmfHeader; + BITMAPINFOHEADER bi; + img_struct *s,*s2; + + if (i>=0){ + validatepage(i); s=&img[page[i]]; + }else{ + x=-i; + if (x>=nextimg){error(258); return;} + s=&img[x]; + if (!s->valid){error(258); return;} + } + + if (!szPrinterName) szPrinterName=(LPSTR)malloc(65536); + dwNameLen=65536; + GetDefaultPrinter(szPrinterName,&dwNameLen); + if((dc=CreateDC(TEXT("WINSPOOL"),szPrinterName,NULL,NULL))==NULL) goto failed; + ZeroMemory(&di,sizeof(DOCINFO)); + di.cbSize=sizeof(DOCINFO); + di.lpszDocName=TEXT("Document"); + if(StartDoc(dc,&di)<=0){DeleteDC(dc); goto failed;} + if(StartPage(dc)<=0){EndDoc(dc); DeleteDC(dc); goto failed;} + + w=GetDeviceCaps(dc,HORZRES); + h=GetDeviceCaps(dc,VERTRES); + + i2=func__newimage(w,h,32,1); + if (i2==-1){EndDoc(dc); DeleteDC(dc); goto failed;} + s2=&img[-i2]; + sub__dontblend(i2,1); + sub__putimage(NULL,NULL,NULL,NULL,i,i2,NULL,NULL,NULL,NULL,8+32); + + ZeroMemory(&bi,sizeof(BITMAPINFOHEADER)); + + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = w; + bi.biHeight = h; + bi.biPlanes = 1; + bi.biBitCount = 32; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; + bi.biXPelsPerMeter = 0; + bi.biYPelsPerMeter = 0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + for (y=0;yoffset32+(y*w),(BITMAPINFO*)&bi, DIB_RGB_COLORS); + } + + sub__freeimage(i2,1); + + if(EndPage(dc)<=0){EndDoc(dc); DeleteDC(dc); goto failed;} + if(EndDoc(dc)<=0){DeleteDC(dc); goto failed;} + DeleteDC(dc); + failed:; + #endif + } + +#endif \ No newline at end of file diff --git a/internal/c/libqb/printer.h b/internal/c/libqb/printer.h new file mode 100644 index 000000000..db13782b9 --- /dev/null +++ b/internal/c/libqb/printer.h @@ -0,0 +1,2 @@ +//forward references +void sub__printimage(int32 i); diff --git a/internal/c/parts/audio/libresample/src/config.h b/internal/c/parts/audio/libresample/src/config.h new file mode 100644 index 000000000..94ae1cea9 --- /dev/null +++ b/internal/c/parts/audio/libresample/src/config.h @@ -0,0 +1,7 @@ +/* Run configure to generate config.h automatically on any + system supported by GNU autoconf. For all other systems, + use this file as a template to create config.h +*/ + +#undef HAVE_INTTYPES_H + diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index e40c70031..a5321e5f3 100644 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -43,6 +43,7 @@ if (midiCaps.dwSupport & MIDICAPS_VOLUME) extern void error(int32 error_number); extern int32 sub_gl_called; +#ifdef QB64_GUI #ifdef DEPENDENCY_GL #ifdef QB64_BACKSLASH_FILESYSTEM @@ -68,6 +69,7 @@ extern int32 sub_gl_called; } #endif +#endif /* #ifdef QB64_BACKSLASH_FILESYSTEM @@ -2152,464 +2154,6 @@ uint8 *redim_preserve_cmem_buffer=(uint8*)malloc(65536);//used for temporary sto #include "myip.cpp" - -void sub_lprint(qbs* str,int32 finish_on_new_line){ - -#ifdef QB64_WINDOWS - -//proposed #1: -//_PRINTIMAGE [i] -//ideas: _ASPECT (maintains aspect ratio) -// (?,?)-(?,?) where ? is a value from 0-1 of the respective paper dimension - -//_PRINTIMAGE i, _SQUAREPIXELS mypic,(0,0)-(0.5,0.5) - -//_PRINTIMAGE [XXXbut what is dimension?)(0,0)[-(1,1)]],i i, _SQUAREPIXELS mypic,(0,0)-(0.5,0.5) - -//_PRINTIMAGE _SQUAREPIXELS i,(0,0)-(0.5,0.5) -//idea: where squarepixels is used the image is printed maintaining aspect ratio within -// target area - - -/* -CDC memDC; - CClientDC dc(this); - - int bmpWidth = 1600; - int bmpHeight = 500; - - memDC.CreateCompatibleDC( &dc ); - - CBitmap bitmap; - - HBITMAP hbmp=(HBITMAP)LoadImage(NULL,"d:\\italy\\florence.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); - - - bitmap.Attach(hbmp); - - BITMAP bm; - bitmap.GetObject(sizeof(BITMAP),&bm); - - CBitmap * pOldBitmap = (CBitmap *) memDC.SelectObject(& bitmap ); - - - if (pOldBitmap == NULL) // if bitmap is very big, better check this ! - { - memDC.DeleteDC(); - - AfxMessageBox("Not enough resource for the bitmap. Either reduce the bitmap dimension or switch to lower screen setting (e.g. 256-color mode), and try again."); - return; - } - - dc.BitBlt(0,0, bm.bmWidth , bm.bmHeight,&memDC,0,0,SRCCOPY); - - CDC prtDC; - CPrintInfo printInfo; - CSize size; - DOCINFO di; - CString szPortName, szAppName, szPrintError; - szAppName.LoadString(AFX_IDS_APP_TITLE); - szPrintError = ""; - - CSize paper_size; //printer paper size in mm - int xLogPPI = 0; - int yLogPPI = 0; - - if( AfxGetApp()->GetPrinterDeviceDefaults(&printInfo.m_pPD->m_pd) ) - { - HDC hDC = printInfo.m_pPD->m_pd.hDC; - if (hDC == NULL) - hDC = printInfo.m_pPD->CreatePrinterDC(); - if(hDC !=NULL) - { - prtDC.Attach(hDC); - paper_size.cx = prtDC.GetDeviceCaps(HORZSIZE); - paper_size.cy = prtDC.GetDeviceCaps(VERTSIZE); - xLogPPI = prtDC.GetDeviceCaps(LOGPIXELSX); - yLogPPI = prtDC.GetDeviceCaps(LOGPIXELSY); - } - else - { - AfxMessageBox("Can not find printer. Please check installed/default printers."); - return; - } - } - int scr_xLogPPI = dc.GetDeviceCaps(LOGPIXELSX); - int scr_yLogPPI = dc.GetDeviceCaps(LOGPIXELSY); - int paper_width = (int) ((double) paper_size.cx * (double) xLogPPI / 25.4); //width of a printed page in pixels - int paper_height = (int) ((double) paper_size.cy * (double) yLogPPI / 25.4); - double ratio_x = (double) xLogPPI / (double) scr_xLogPPI; - double ratio_y = (double) yLogPPI / (double) scr_yLogPPI; - - CString strPageNumber = ""; - - int page_info_left = (int) ( (double) paper_width * 0.9 ); - int page_info_right = paper_width; - int page_info_top = (int) ( (double) paper_height * 0.99); - int page_info_bottom = paper_height; - CRect page_info_rect = CRect(page_info_left, page_info_top, - page_info_right,page_info_bottom ); - int printed_pages = 0; - int total_print_pages = 0; - BOOL bAbort_print = FALSE; - - // calculate pages - int total_pages = (bmpWidth * ratio_x + paper_width - 1 ) / paper_width; - //pop up printer dialog - CPrintDialog prtDlg(FALSE, PD_PAGENUMS); - - prtDlg.m_pd.nMinPage = 1; - prtDlg.m_pd.nMaxPage = total_pages; - prtDlg.m_pd.nFromPage = 1; - prtDlg.m_pd.nToPage = total_pages; - - if(prtDlg.DoModal() == IDOK ) - { - memset(&di, 0, sizeof(DOCINFO)); - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = szAppName; - szPortName = prtDlg.GetPortName(); - di.lpszOutput = szPortName; - prtDC.m_bPrinting = TRUE; - } - else - return; //Cancel button pressed, don't forget this! - - if(prtDC.StartDoc(&di) == -1) - { - AfxMessageBox("Printing error occured. Unable to find printer."); - prtDC.Detach(); - prtDC.DeleteDC(); - return; - } - - prtDC.SetMapMode(MM_TEXT); - - int i = 0; - for(i = 0; i < total_pages; i++) - { - prtDC.StartPage(); - strPageNumber.Format("Page:%d of %d", ++printed_pages, total_print_pages ); - - if ( i == (total_pages - 1) && total_pages > 1 ) //last page - { - int last_bmpWidth = bmpWidth - paper_width / ratio_x * i; - prtDC.StretchBlt(0, 0, last_bmpWidth * ratio_x, bmpHeight* ratio_y, &memDC, - paper_width * i / ratio_x, 0, last_bmpWidth, bmpHeight, SRCCOPY); - } - else - prtDC.StretchBlt(0, 0, paper_width, bmpHeight* ratio_y, &memDC, - paper_width * i / ratio_x, 0, paper_width / ratio_x , bmpHeight, SRCCOPY); - prtDC.TextOut(page_info_rect.left, page_info_rect.top, strPageNumber ); - - prtDC.EndPage(); - } - memDC.SelectObject(pOldBitmap); - - memDC.DeleteDC(); - - prtDC.EndDoc(); - prtDC.Detach(); - prtDC.DeleteDC(); -*/ - -//assumes 80x60 characters per page - -/* -static HWND hwnd; -hwnd=GetDesktopWindow(); -static RECT rect; -GetWindowRect(hwnd,&rect); -static int32 x,y; -x=rect.right-rect.left; -y=rect.bottom-rect.top; -static HDC hdc; -hdc=GetDC(hwnd); -static HDC hdc2; -hdc2=CreateCompatibleDC(hdc); -static HBITMAP bitmap; -bitmap=CreateCompatibleBitmap(hdc,x,y); - -SelectObject(hdc2,bitmap); -BitBlt( hdc2, - 0,0, - x,y, - hdc, - 0,0, - SRCCOPY); - - - static BITMAPFILEHEADER bmfHeader; - static BITMAPINFOHEADER bi; - bi.biSize = sizeof(BITMAPINFOHEADER); - bi.biWidth = x; - bi.biHeight = y; - bi.biPlanes = 1; - bi.biBitCount = 32; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; - bi.biXPelsPerMeter = 0; - bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; - bi.biClrImportant = 0; - -static int32 i,i2,i3; -i2=func__dest(); -i=func__newimage(x,y,32,1); -sub__dest(i); -GetDIBits(hdc2,bitmap,0,y,write_page->offset,(BITMAPINFO*)&bi, DIB_RGB_COLORS); -sub__setalpha(255,NULL,NULL,NULL,0); - -i3=func__newimage(x,y,32,1); -sub__dontblend(i,1); -sub__dontblend(i3,1); -sub__putimage(NULL,0,y-1,NULL,x-1,0,i,i3,NULL,NULL,NULL,NULL,NULL,NULL,15); -sub__freeimage(i,1); -sub__blend(i3,1); -sub__dest(i2); - -DeleteObject(bitmap); -DeleteDC(hdc2); -ReleaseDC(NULL,hdc); - -*/ - - - - -TCHAR szString[81] = TEXT("01234567890123456789012345678901234567890123456789012345678901234567890123456789"); - - - -static LPSTR szPrinterName=NULL; -static DWORD dwNameLen; -static HDC dc; -static DOCINFO di; -static HFONT hFont, hOldFont; -static double logPixelsY; -static TEXTMETRIC tm; - -static uint32 w,h; -int32 x; -int32 y; - -if (!szPrinterName) szPrinterName=(LPSTR)malloc(65536); -dwNameLen=65536; -GetDefaultPrinter(szPrinterName,&dwNameLen); -if((dc=CreateDC(TEXT("WINSPOOL"),szPrinterName,NULL,NULL))==NULL) goto failed; -ZeroMemory(&di,sizeof(DOCINFO)); -di.cbSize=sizeof(DOCINFO); -di.lpszDocName=TEXT("MyPic"); -if(StartDoc(dc,&di)<=0){DeleteDC(dc); goto failed;} -if(StartPage(dc)<=0){EndDoc(dc); DeleteDC(dc); goto failed;} - -/* -int32 paper_size_cx,paper_size_cy; -int32 xLogPPI,yLogPPI; - paper_size_cx = GetDeviceCaps(dc,HORZSIZE); - paper_size_cy = GetDeviceCaps(dc,VERTSIZE); - xLogPPI = GetDeviceCaps(dc,LOGPIXELSX); - yLogPPI = GetDeviceCaps(dc,LOGPIXELSY); -int32 paper_width,paper_height; -w= paper_width = (int) ((double) paper_size_cx * (double) xLogPPI / 25.4); //width of a printed page in pixels -h= paper_height = (int) ((double) paper_size_cy * (double) yLogPPI / 25.4); -*/ - - -//http://support.microsoft.com/kb/122037 -// Init our pt struct in case escape not supported -int32 pt_x,pt_y; -pt_x=0; pt_y=0; -// Locate the upper left corner of the printable area - - - - - -/* -// Figure out how much you need to offset output to produce the left -// and top margins for the output in the printer. Note the -// use of the "max" macro. It is possible that you are asking for -// margins that are not possible on this printer. For example, the HP -// LaserJet has a 0.25" unprintable area so we cannot get margins of -// 0.1". -int32 xOffset,yOffset; -xOffset = max (0, GetDeviceCaps (hPrnDC, LOGPIXELSX) * - nInchesWeWant - pt_x); -yOffset = max (0, GetDeviceCaps (hPrnDC, LOGPIXELSY) * - nInchesWeWant - pt_y); - - // When doing all the output, you can either offset it by the above - // values or call SetViewportOrg() to set the point (0,0) at - // the margin offset you calculated. - - SetViewportOrg (hPrnDC, xOffset, yOffset); - all other output here -*/ - - - - - - - - - - - - -w=GetDeviceCaps(dc,HORZRES); -h=GetDeviceCaps(dc,VERTRES); -double margin_x,margin_y; -margin_x = GetDeviceCaps(dc, PHYSICALOFFSETX);//margins are in device units -margin_y = GetDeviceCaps(dc, PHYSICALOFFSETY); -double size_x,size_y; -size_x = GetDeviceCaps(dc,PHYSICALWIDTH);//in device units -size_y = GetDeviceCaps(dc,PHYSICALHEIGHT); -//note: the HDC represents an area from (not including) the top/left margin to the last point on the paper page -// so w&h are rescaled based on the ratio between the full size without the margin and full size (all in device units) -w=((double)w)*((size_x-margin_x)/size_x); -h=((double)h)*((size_y-margin_y)/size_y); -w--; h--;//ensure bottom/right pixel is within printable area - - - -int32 i; -i=func__newimage(w,h,32,1); - - static BITMAPFILEHEADER bmfHeader; - static BITMAPINFOHEADER bi; - bi.biSize = sizeof(BITMAPINFOHEADER); - bi.biWidth = w; - bi.biHeight = h; - bi.biPlanes = 1; - bi.biBitCount = 32; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; - bi.biXPelsPerMeter = 0; - bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; - bi.biClrImportant = 0; - - -//GetDIBits(hdc2,bitmap,0,y,write_page->offset,(BITMAPINFO*)&bi, DIB_RGB_COLORS); - -uint32 *d; -d=(uint32*)malloc(w*h*4); - -int32 xx; - -xx=0; -for (y=0;y 0 OR DEPENDENCY(DEPENDENCY_CONSOLE_ONLY) = 0 THEN + x = INSTR(a$, " -o"): a$ = LEFT$(a$, x - 1) + " -lwinmm" + RIGHT$(a$, LEN(a$) - x + 1) + END IF + + a$ = StrRemove(a$, "-lksguid") + IF DEPENDENCY(DEPENDENCY_AUDIO_OUT) THEN + x = INSTR(a$, " -o"): a$ = LEFT$(a$, x - 1) + " -lksguid" + RIGHT$(a$, LEN(a$) - x + 1) + END IF + + a$ = StrRemove(a$, "-ldxguid") + IF DEPENDENCY(DEPENDENCY_AUDIO_OUT) THEN + x = INSTR(a$, " -o"): a$ = LEFT$(a$, x - 1) + " -ldxguid" + RIGHT$(a$, LEN(a$) - x + 1) + END IF + + a$ = StrRemove(a$, "-lole32") + IF DEPENDENCY(DEPENDENCY_AUDIO_OUT) THEN + x = INSTR(a$, " -o"): a$ = LEFT$(a$, x - 1) + " -lole32" + RIGHT$(a$, LEN(a$) - x + 1) + END IF + + a$ = StrRemove(a$, "-lgdi32") + IF DEPENDENCY(DEPENDENCY_ICON) <> 0 OR DEPENDENCY(DEPENDENCY_SCREENIMAGE) <> 0 OR DEPENDENCY(DEPENDENCY_PRINTER) <> 0 THEN + x = INSTR(a$, " -o"): a$ = LEFT$(a$, x - 1) + " -lgdi32" + RIGHT$(a$, LEN(a$) - x + 1) + END IF + IF inline_DATA = 0 THEN 'add data.o? IF DataOffset THEN @@ -11545,6 +11630,10 @@ tpos = 1 DO token$ = MID$(cmdline$, tpos, 2) ')) SELECT CASE token$ + CASE "-g" 'non-GUI environment ($CONSOLE:ONLY in effect) + DEPENDENCY(DEPENDENCY_CONSOLE_ONLY) = DEPENDENCY(DEPENDENCY_CONSOLE_ONLY) OR 2 + NoIDEMode = 1 'Implies -c + Console = 1 CASE "-q" 'Building a Qloud program Cloud = 1 ConsoleMode = 1 'Implies -x @@ -21072,7 +21161,7 @@ SUB xprint (a$, ca$, n) u$ = str2$(uniquenumber) l$ = "PRINT" -IF ASC(a$) = 76 THEN lp = 1: lp$ = "l": l$ = "LPRINT": PRINT #12, "tab_LPRINT=1;" '"L" +IF ASC(a$) = 76 THEN lp = 1: lp$ = "l": l$ = "LPRINT": PRINT #12, "tab_LPRINT=1;": DEPENDENCY(DEPENDENCY_PRINTER) = 1 '"L" 'PRINT USING? IF n >= 2 THEN @@ -23777,6 +23866,31 @@ Error_Happened = 1 Error_Message = a$ END SUB +FUNCTION StrRemove$ (myString$, whatToRemove$) 'noncase sensitive +a$ = myString$ +b$ = LCASE$(whatToRemove$) +i = INSTR(LCASE$(a$), b$) +DO WHILE i + a$ = LEFT$(a$, i - 1) + RIGHT$(a$, LEN(a$) - i - LEN(b$) + 1) + i = INSTR(LCASE$(a$), b$) +LOOP +StrRemove$ = a$ +END FUNCTION + +FUNCTION StrReplace$ (myString$, find$, replaceWith$) 'noncase sensitive +IF LEN(myString$) = 0 THEN EXIT FUNCTION +a$ = myString$ +b$ = LCASE$(find$) +basei = 1 +i = INSTR(basei, LCASE$(a$), b$) +DO WHILE i + a$ = LEFT$(a$, i - 1) + replaceWith$ + RIGHT$(a$, LEN(a$) - i - LEN(b$) + 1) + basei = i + LEN(replaceWith$) + i = INSTR(basei, LCASE$(a$), b$) +LOOP +StrReplace$ = a$ +END FUNCTION + '$INCLUDE:'subs_functions\extensions\opengl\opengl_methods.bas' diff --git a/source/subs_functions/subs_functions.bas b/source/subs_functions/subs_functions.bas index 5fd1f1514..2f393292c 100644 --- a/source/subs_functions/subs_functions.bas +++ b/source/subs_functions/subs_functions.bas @@ -521,7 +521,7 @@ id.NoCloud = 1 regid clearid -id.n = "_PRINTIMAGE" +id.n = "_PRINTIMAGE": id.Dependency = DEPENDENCY_PRINTER id.subfunc = 2 id.callname = "sub__printimage" id.args = 1 @@ -552,7 +552,7 @@ id.NoCloud = 1 regid clearid -id.n = "_SCREENIMAGE" +id.n = "_SCREENIMAGE": id.Dependency = DEPENDENCY_SCREENIMAGE id.subfunc = 1 id.callname = "func__screenimage" id.args = 4 @@ -649,7 +649,7 @@ id.ret = LONGTYPE - ISPOINTER regid clearid -id.n = "_OPENHOST" +id.n = "_OPENHOST": id.Dependency = DEPENDENCY_SOCKETS id.subfunc = 1 id.callname = "func__openhost" id.args = 1 @@ -686,7 +686,7 @@ id.ret = LONGTYPE - ISPOINTER regid clearid -id.n = "_OPENCLIENT" +id.n = "_OPENCLIENT": id.Dependency = DEPENDENCY_SOCKETS id.subfunc = 1 id.callname = "func__openclient" id.args = 1 @@ -753,7 +753,7 @@ id.arg = MKL$(DOUBLETYPE - ISPOINTER) regid clearid -id.n = "_ICON" +id.n = "_ICON": id.Dependency = DEPENDENCY_ICON id.subfunc = 2 id.callname = "sub__icon" id.args = 2 @@ -2722,7 +2722,7 @@ id.arg = MKL$(STRINGTYPE - ISPOINTER) regid clearid -id.n = "LPRINT" +id.n = "LPRINT": id.Dependency = DEPENDENCY_PRINTER id.subfunc = 2 id.callname = "qbs_lprint" 'not called directly id.args = 1 @@ -2731,7 +2731,7 @@ id.NoCloud = 1 regid clearid -id.n = "LPOS" +id.n = "LPOS": id.Dependency = DEPENDENCY_PRINTER id.subfunc = 1 id.callname = "func_lpos" id.args = 1