1
1
Fork 0
mirror of https://github.com/QB64Official/qb64.git synced 2024-09-28 11:17:47 +00:00

Indentation work. No actual code changes.

This commit is contained in:
FellippeHeitor 2018-06-30 12:16:59 -03:00
parent 729a1dd465
commit 12df99c8da
28 changed files with 31845 additions and 31845 deletions

View file

@ -1,286 +1,286 @@
//Fill out dependency macros //Fill out dependency macros
#ifndef DEPENDENCY_NO_SOCKETS #ifndef DEPENDENCY_NO_SOCKETS
#define DEPENDENCY_SOCKETS #define DEPENDENCY_SOCKETS
#endif #endif
#ifndef DEPENDENCY_NO_PRINTER #ifndef DEPENDENCY_NO_PRINTER
#define DEPENDENCY_PRINTER #define DEPENDENCY_PRINTER
#endif #endif
#ifndef DEPENDENCY_NO_ICON #ifndef DEPENDENCY_NO_ICON
#define DEPENDENCY_ICON #define DEPENDENCY_ICON
#endif #endif
#ifndef DEPENDENCY_NO_SCREENIMAGE #ifndef DEPENDENCY_NO_SCREENIMAGE
#define DEPENDENCY_SCREENIMAGE #define DEPENDENCY_SCREENIMAGE
#endif #endif
#ifndef INC_COMMON_CPP #ifndef INC_COMMON_CPP
#define INC_COMMON_CPP #define INC_COMMON_CPP
#include "os.h" #include "os.h"
#define QB64_GL1 #define QB64_GL1
#define QB64_GLUT #define QB64_GLUT
#ifdef DEPENDENCY_CONSOLE_ONLY #ifdef DEPENDENCY_CONSOLE_ONLY
#undef QB64_GLUT #undef QB64_GLUT
#else #else
#define QB64_GUI #define QB64_GUI
#endif #endif
//core //core
#ifdef QB64_GUI #ifdef QB64_GUI
#ifdef QB64_GLUT #ifdef QB64_GLUT
//This file only contains header stuff //This file only contains header stuff
#include "parts/core/src.c" #include "parts/core/src.c"
#endif #endif
#endif #endif
#ifdef QB64_WINDOWS #ifdef QB64_WINDOWS
#ifndef QB64_GUI #ifndef QB64_GUI
#undef int64 //definition of int64 from os.h conflicts with a definition within windows.h, temporarily undefine then redefine #undef int64 //definition of int64 from os.h conflicts with a definition within windows.h, temporarily undefine then redefine
#include <windows.h> #include <windows.h>
#define int64 __int64 #define int64 __int64
#endif #endif
#include <shfolder.h> #include <shfolder.h>
#include <float.h> #include <float.h>
#include <winbase.h> #include <winbase.h>
#endif #endif
//common includes //common includes
#include <stdio.h> #include <stdio.h>
#ifdef QB64_MACOSX #ifdef QB64_MACOSX
#include <cmath> #include <cmath>
#else #else
//#include <math.h> //<-causes overloading abs conflicts in Windows //#include <math.h> //<-causes overloading abs conflicts in Windows
#include <cmath> #include <cmath>
#endif #endif
#include <time.h> #include <time.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
//OS/compiler specific includes //OS/compiler specific includes
#ifdef QB64_WINDOWS #ifdef QB64_WINDOWS
#include <direct.h> #include <direct.h>
#ifdef DEPENDENCY_PRINTER #ifdef DEPENDENCY_PRINTER
#include <winspool.h> #include <winspool.h>
#endif #endif
#include <csignal> #include <csignal>
#include <process.h> //required for multi-threading #include <process.h> //required for multi-threading
#if defined DEPENDENCY_AUDIO_OUT || defined QB64_GUI #if defined DEPENDENCY_AUDIO_OUT || defined QB64_GUI
#include <mmsystem.h> #include <mmsystem.h>
#endif #endif
#else #else
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#ifndef QB64_MACOSX #ifndef QB64_MACOSX
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#endif #endif
#ifdef QB64_GUI #ifdef QB64_GUI
#ifdef QB64_GLUT #ifdef QB64_GLUT
#include "parts/core/gl_headers/opengl_org_registery/glext.h" #include "parts/core/gl_headers/opengl_org_registery/glext.h"
#endif #endif
#endif #endif
using namespace std; using namespace std;
//QB64 string descriptor structure //QB64 string descriptor structure
struct qbs_field{ struct qbs_field{
int32 fileno; int32 fileno;
int64 fileid; int64 fileid;
int64 size; int64 size;
int64 offset; int64 offset;
}; };
struct qbs{ struct qbs{
uint8 *chr;//a 32 bit pointer to the string's data uint8 *chr;//a 32 bit pointer to the string's data
int32 len;//must be signed for comparisons against signed int32s int32 len;//must be signed for comparisons against signed int32s
uint8 in_cmem;//set to 1 if in the conventional memory DBLOCK uint8 in_cmem;//set to 1 if in the conventional memory DBLOCK
uint16 *cmem_descriptor; uint16 *cmem_descriptor;
uint16 cmem_descriptor_offset; uint16 cmem_descriptor_offset;
uint32 listi;//the index in the list of strings that references it uint32 listi;//the index in the list of strings that references it
uint8 tmp;//set to 1 if the string can be deleted immediately after being processed uint8 tmp;//set to 1 if the string can be deleted immediately after being processed
uint32 tmplisti;//the index in the list of strings that references it uint32 tmplisti;//the index in the list of strings that references it
uint8 fixed;//fixed length string uint8 fixed;//fixed length string
uint8 readonly;//set to 1 if string is read only uint8 readonly;//set to 1 if string is read only
qbs_field *field; qbs_field *field;
}; };
struct img_struct{ struct img_struct{
void *lock_offset; void *lock_offset;
int64 lock_id; int64 lock_id;
uint8 valid;//0,1 0=invalid uint8 valid;//0,1 0=invalid
uint8 text;//if set, surface is a text surface uint8 text;//if set, surface is a text surface
uint8 console;//dummy surface to absorb unimplemented console functionality uint8 console;//dummy surface to absorb unimplemented console functionality
uint16 width,height; uint16 width,height;
uint8 bytes_per_pixel;//1,2,4 uint8 bytes_per_pixel;//1,2,4
uint8 bits_per_pixel;//1,2,4,8,16(text),32 uint8 bits_per_pixel;//1,2,4,8,16(text),32
uint32 mask;//1,3,0xF,0xFF,0xFFFF,0xFFFFFFFF uint32 mask;//1,3,0xF,0xFF,0xFFFF,0xFFFFFFFF
uint16 compatible_mode;//0,1,2,7,8,9,10,11,12,13,32,256 uint16 compatible_mode;//0,1,2,7,8,9,10,11,12,13,32,256
uint32 color,background_color,draw_color; uint32 color,background_color,draw_color;
uint32 font;//8,14,16,? uint32 font;//8,14,16,?
int16 top_row,bottom_row;//VIEW PRINT settings, unique (as in QB) to each "page" int16 top_row,bottom_row;//VIEW PRINT settings, unique (as in QB) to each "page"
int16 cursor_x,cursor_y;//unique (as in QB) to each "page" int16 cursor_x,cursor_y;//unique (as in QB) to each "page"
uint8 cursor_show, cursor_firstvalue, cursor_lastvalue; uint8 cursor_show, cursor_firstvalue, cursor_lastvalue;
union{ union{
uint8 *offset; uint8 *offset;
uint32 *offset32; uint32 *offset32;
}; };
uint32 flags; uint32 flags;
uint32 *pal; uint32 *pal;
int32 transparent_color;//-1 means no color is transparent int32 transparent_color;//-1 means no color is transparent
uint8 alpha_disabled; uint8 alpha_disabled;
uint8 holding_cursor; uint8 holding_cursor;
uint8 print_mode; uint8 print_mode;
//BEGIN apm ('active page migration') //BEGIN apm ('active page migration')
//everything between apm points is migrated during active page changes //everything between apm points is migrated during active page changes
//note: apm data is only relevent to graphics modes //note: apm data is only relevent to graphics modes
uint8 apm_p1; uint8 apm_p1;
int32 view_x1,view_y1,view_x2,view_y2; int32 view_x1,view_y1,view_x2,view_y2;
int32 view_offset_x,view_offset_y; int32 view_offset_x,view_offset_y;
float x,y; float x,y;
uint8 clipping_or_scaling; uint8 clipping_or_scaling;
float scaling_x,scaling_y,scaling_offset_x,scaling_offset_y; float scaling_x,scaling_y,scaling_offset_x,scaling_offset_y;
float window_x1,window_y1,window_x2,window_y2; float window_x1,window_y1,window_x2,window_y2;
double draw_ta; double draw_ta;
double draw_scale; double draw_scale;
uint8 apm_p2; uint8 apm_p2;
//END apm //END apm
}; };
//img_struct flags //img_struct flags
#define IMG_FREEPAL 1 //free palette data before freeing image #define IMG_FREEPAL 1 //free palette data before freeing image
#define IMG_SCREEN 2 //img is linked to other screen pages #define IMG_SCREEN 2 //img is linked to other screen pages
#define IMG_FREEMEM 4 //if set, it means memory must be freed #define IMG_FREEMEM 4 //if set, it means memory must be freed
//QB64 internal variable type flags (internally referenced by some C functions) //QB64 internal variable type flags (internally referenced by some C functions)
#define ISSTRING 1073741824 #define ISSTRING 1073741824
#define ISFLOAT 536870912 #define ISFLOAT 536870912
#define ISUNSIGNED 268435456 #define ISUNSIGNED 268435456
#define ISPOINTER 134217728 #define ISPOINTER 134217728
#define ISFIXEDLENGTH 67108864 //only set for strings with pointer flag #define ISFIXEDLENGTH 67108864 //only set for strings with pointer flag
#define ISINCONVENTIONALMEMORY 33554432 #define ISINCONVENTIONALMEMORY 33554432
#define ISOFFSETINBITS 16777216 #define ISOFFSETINBITS 16777216
struct ontimer_struct{ struct ontimer_struct{
uint8 allocated; uint8 allocated;
uint32 id;//the event ID to trigger (0=no event) uint32 id;//the event ID to trigger (0=no event)
int64 pass;//the value to pass to the triggered event (only applicable to ON ... CALL ...(x) int64 pass;//the value to pass to the triggered event (only applicable to ON ... CALL ...(x)
uint8 active;//0=OFF, 1=ON, 2=STOP uint8 active;//0=OFF, 1=ON, 2=STOP
uint8 state;//0=untriggered,1=triggered uint8 state;//0=untriggered,1=triggered
double seconds;//how many seconds between events double seconds;//how many seconds between events
double last_time;//the last time this event was triggered double last_time;//the last time this event was triggered
}; };
struct onkey_struct{ struct onkey_struct{
uint32 id;//the event ID to trigger (0=no event) uint32 id;//the event ID to trigger (0=no event)
int64 pass;//the value to pass to the triggered event (only applicable to ON ... CALL ...(x) int64 pass;//the value to pass to the triggered event (only applicable to ON ... CALL ...(x)
uint8 active;//0=OFF, 1=ON, 2=STOP uint8 active;//0=OFF, 1=ON, 2=STOP
uint8 state;//0=untriggered,1=triggered,2=in progress(TIMER only),2+=multiple events queued(KEY only) uint8 state;//0=untriggered,1=triggered,2=in progress(TIMER only),2+=multiple events queued(KEY only)
uint32 keycode;//32-bit code, same as what _KEYHIT returns uint32 keycode;//32-bit code, same as what _KEYHIT returns
uint32 keycode_alternate;//an alternate keycode which may also trigger event uint32 keycode_alternate;//an alternate keycode which may also trigger event
uint8 key_scancode; uint8 key_scancode;
uint8 key_flags; uint8 key_flags;
//flags: //flags:
//0 No keyboard flag, 1-3 Either Shift key, 4 Ctrl key, 8 Alt key,32 NumLock key,64 Caps Lock key, 128 Extended keys on a 101-key keyboard //0 No keyboard flag, 1-3 Either Shift key, 4 Ctrl key, 8 Alt key,32 NumLock key,64 Caps Lock key, 128 Extended keys on a 101-key keyboard
//To specify multiple shift states, add the values together. For example, a value of 12 specifies that the user-defined key is used in combination with the Ctrl and Alt keys. //To specify multiple shift states, add the values together. For example, a value of 12 specifies that the user-defined key is used in combination with the Ctrl and Alt keys.
qbs *text; qbs *text;
}; };
struct onstrig_struct{ struct onstrig_struct{
uint32 id;//the event ID to trigger (0=no event) uint32 id;//the event ID to trigger (0=no event)
int64 pass;//the value to pass to the triggered event (only applicable to ON ... CALL ...(x) int64 pass;//the value to pass to the triggered event (only applicable to ON ... CALL ...(x)
uint8 active;//0=OFF, 1=ON, 2=STOP uint8 active;//0=OFF, 1=ON, 2=STOP
uint8 state;//0=untriggered,1=triggered,2=in progress(TIMER only),2+=multiple events queued(KEY only) uint8 state;//0=untriggered,1=triggered,2=in progress(TIMER only),2+=multiple events queued(KEY only)
}; };
struct byte_element_struct struct byte_element_struct
{ {
uint64 offset; uint64 offset;
int32 length; int32 length;
}; };
struct device_struct{ struct device_struct{
int32 used; int32 used;
int32 type; int32 type;
//0=Unallocated //0=Unallocated
//1=Joystick/Gamepad //1=Joystick/Gamepad
//2=Keybaord //2=Keybaord
//3=Mouse //3=Mouse
char *name; char *name;
int32 connected; int32 connected;
int32 lastbutton; int32 lastbutton;
int32 lastaxis; int32 lastaxis;
int32 lastwheel; int32 lastwheel;
//-------------- //--------------
int32 max_events; int32 max_events;
int32 queued_events; int32 queued_events;
uint8 *events;//the structure and size of the events depends greatly on the device and its capabilities uint8 *events;//the structure and size of the events depends greatly on the device and its capabilities
int32 event_size; int32 event_size;
//-------------- //--------------
uint8 STRIG_button_pressed[256];//checked and cleared by the STRIG function uint8 STRIG_button_pressed[256];//checked and cleared by the STRIG function
//-------------- //--------------
void *handle_pointer;//handle as pointer void *handle_pointer;//handle as pointer
int64 handle_int;//handle as integer int64 handle_int;//handle as integer
char *description;//description provided by manufacturer char *description;//description provided by manufacturer
int64 product_id; int64 product_id;
int64 vendor_id; int64 vendor_id;
int32 buttons; int32 buttons;
int32 axes; int32 axes;
int32 balls; int32 balls;
int32 hats; int32 hats;
}; };
//device_struct constants //device_struct constants
#define QUEUED_EVENTS_LIMIT 1024 #define QUEUED_EVENTS_LIMIT 1024
#define DEVICETYPE_CONTROLLER 1 #define DEVICETYPE_CONTROLLER 1
#define DEVICETYPE_KEYBOARD 2 #define DEVICETYPE_KEYBOARD 2
#define DEVICETYPE_MOUSE 3 #define DEVICETYPE_MOUSE 3
struct mem_block{ struct mem_block{
ptrszint offset; ptrszint offset;
ptrszint size; ptrszint size;
int64 lock_id;//64-bit key, must be present at lock's offset or memory region is invalid int64 lock_id;//64-bit key, must be present at lock's offset or memory region is invalid
ptrszint lock_offset;//pointer to lock ptrszint lock_offset;//pointer to lock
ptrszint type; ptrszint type;
/* /*
memorytype (4 bytes, but only the first used, for flags): memorytype (4 bytes, but only the first used, for flags):
1 integer values 1 integer values
2 unsigned (set in conjunction with integer) 2 unsigned (set in conjunction with integer)
4 floating point values 4 floating point values
8 char string(s) 'element-size is the memory size of 1 string 8 char string(s) 'element-size is the memory size of 1 string
*/ */
ptrszint elementsize; ptrszint elementsize;
int32 image; int32 image;
}; };
struct mem_lock{ struct mem_lock{
uint64 id; uint64 id;
int32 type;//required to know what action to take (if any) when a request is made to free the block int32 type;//required to know what action to take (if any) when a request is made to free the block
//0=no security (eg. user defined block from _OFFSET) //0=no security (eg. user defined block from _OFFSET)
//1=C-malloc'ed block //1=C-malloc'ed block
//2=image //2=image
//3=sub/function scope block //3=sub/function scope block
//4=array //4=array
//---- type specific variables follow ---- //---- type specific variables follow ----
void *offset;//used by malloc'ed blocks to free them void *offset;//used by malloc'ed blocks to free them
}; };
#endif //INC_COMMON_CPP #endif //INC_COMMON_CPP

File diff suppressed because it is too large Load diff

View file

@ -1,71 +1,71 @@
#ifndef INC_LIBQB_H #ifndef INC_LIBQB_H
#define INC_LIBQB_H #define INC_LIBQB_H
#include "common.h" #include "common.h"
void error(int32 error_number); void error(int32 error_number);
extern uint32 new_error; extern uint32 new_error;
extern uint32 error_err; //=0; extern uint32 error_err; //=0;
extern double error_erl; //=0; extern double error_erl; //=0;
extern uint32 error_occurred; extern uint32 error_occurred;
extern uint32 error_goto_line; extern uint32 error_goto_line;
extern uint32 error_handling; extern uint32 error_handling;
extern uint32 error_retry; extern uint32 error_retry;
void sub_shell4(qbs*,int32);//_DONTWAIT & _HIDE void sub_shell4(qbs*,int32);//_DONTWAIT & _HIDE
int32 func__source(); int32 func__source();
int32 func_pos(int32 ignore); int32 func_pos(int32 ignore);
void sub__printimage(int32 i); void sub__printimage(int32 i);
double func_timer(double accuracy,int32 passed); double func_timer(double accuracy,int32 passed);
int32 func__newimage(int32 x,int32 y,int32 bpp,int32 passed); int32 func__newimage(int32 x,int32 y,int32 bpp,int32 passed);
void display(); void display();
void validatepage(int32); void validatepage(int32);
void sub__dest(int32); void sub__dest(int32);
void sub__source(int32); void sub__source(int32);
int32 func__printwidth(qbs*,int32,int32); int32 func__printwidth(qbs*,int32,int32);
void sub_cls(int32,uint32,int32); void sub_cls(int32,uint32,int32);
void qbs_print(qbs*,int32); void qbs_print(qbs*,int32);
int32 func__copyimage(int32 i,int32 mode,int32 passed); int32 func__copyimage(int32 i,int32 mode,int32 passed);
int32 func__dest(); int32 func__dest();
int32 func__display(); int32 func__display();
void qbg_sub_view_print(int32,int32,int32); void qbg_sub_view_print(int32,int32,int32);
qbs *qbs_new(int32,uint8); qbs *qbs_new(int32,uint8);
qbs *qbs_new_txt(const char*); qbs *qbs_new_txt(const char*);
qbs *qbs_add(qbs*,qbs*); qbs *qbs_add(qbs*,qbs*);
qbs *qbs_set(qbs*,qbs*); qbs *qbs_set(qbs*,qbs*);
void qbg_sub_window(float,float,float,float,int32); void qbg_sub_window(float,float,float,float,int32);
extern int32 autodisplay; extern int32 autodisplay;
//GFS forward references //GFS forward references
int32 gfs_eof_passed(int32 i); int32 gfs_eof_passed(int32 i);
int32 gfs_eof_reached(int32 i); int32 gfs_eof_reached(int32 i);
int64 gfs_getpos(int32 i); int64 gfs_getpos(int32 i);
int32 gfs_fileno_valid(int32 f); int32 gfs_fileno_valid(int32 f);
int32 gfs_fileno_freefile();//like FREEFILE int32 gfs_fileno_freefile();//like FREEFILE
void gfs_fileno_use(int32 f, int32 i); void gfs_fileno_use(int32 f, int32 i);
int32 gfs_open(qbs *filename,int32 access,int32 restrictions, int32 how); int32 gfs_open(qbs *filename,int32 access,int32 restrictions, int32 how);
int32 gfs_close(int32 i); int32 gfs_close(int32 i);
int64 gfs_lof(int32 i); int64 gfs_lof(int32 i);
int32 gfs_setpos(int32 i, int64 position); int32 gfs_setpos(int32 i, int64 position);
int32 gfs_write(int32 i,int64 position,uint8 *data,int64 size); int32 gfs_write(int32 i,int64 position,uint8 *data,int64 size);
int32 gfs_read(int32 i,int64 position,uint8 *data,int64 size); int32 gfs_read(int32 i,int64 position,uint8 *data,int64 size);
int64 gfs_read_bytes(); int64 gfs_read_bytes();
extern uint8 cmem[1114099];//16*65535+65535+3 (enough for highest referencable dword in conv memory) extern uint8 cmem[1114099];//16*65535+65535+3 (enough for highest referencable dword in conv memory)
//keyhit cyclic buffer //keyhit cyclic buffer
extern int64 keyhit[8192]; extern int64 keyhit[8192];
// keyhit specific internal flags: (stored in high 32-bits) // keyhit specific internal flags: (stored in high 32-bits)
// &4294967296->numpad was used // &4294967296->numpad was used
extern int32 keyhit_nextfree; extern int32 keyhit_nextfree;
extern int32 keyhit_next; extern int32 keyhit_next;
//note: if full, the oldest message is discarded to make way for the new message //note: if full, the oldest message is discarded to make way for the new message
extern uint8 port60h_event[256]; extern uint8 port60h_event[256];
extern int32 port60h_events; extern int32 port60h_events;
extern int32 window_exists; extern int32 window_exists;
extern int32 no_control_characters2; extern int32 no_control_characters2;
extern qbs *qbs_lcase(qbs *str); extern qbs *qbs_lcase(qbs *str);
extern qbs *qbs_ucase(qbs *str); extern qbs *qbs_ucase(qbs *str);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -2,298 +2,298 @@
int32 requestedKeyboardOverlayImage=0; int32 requestedKeyboardOverlayImage=0;
#ifndef QB64_GUI //begin stubs #ifndef QB64_GUI //begin stubs
//STUB: simulate generating a hardware surface //STUB: simulate generating a hardware surface
int32 new_hardware_img(int32 x, int32 y, uint32 *pixels, int32 flags){ int32 new_hardware_img(int32 x, int32 y, uint32 *pixels, int32 flags){
//create hardware img //create hardware img
int32 handle; int32 handle;
hardware_img_struct* hardware_img; hardware_img_struct* hardware_img;
handle=list_add(hardware_img_handles); handle=list_add(hardware_img_handles);
hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle); hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle);
hardware_img->w=x; hardware_img->w=x;
hardware_img->h=y; hardware_img->h=y;
hardware_img->dest_context_handle=0; hardware_img->dest_context_handle=0;
hardware_img->depthbuffer_handle=0; hardware_img->depthbuffer_handle=0;
hardware_img->pending_commands=0; hardware_img->pending_commands=0;
hardware_img->remove=0; hardware_img->remove=0;
hardware_img->alpha_disabled=0; hardware_img->alpha_disabled=0;
hardware_img->depthbuffer_mode=DEPTHBUFFER_MODE__ON; hardware_img->depthbuffer_mode=DEPTHBUFFER_MODE__ON;
hardware_img->valid=1; hardware_img->valid=1;
hardware_img->source_state.PO2_fix=PO2_FIX__OFF; hardware_img->source_state.PO2_fix=PO2_FIX__OFF;
hardware_img->source_state.texture_wrap=TEXTURE_WRAP_MODE__UNKNOWN; hardware_img->source_state.texture_wrap=TEXTURE_WRAP_MODE__UNKNOWN;
hardware_img->source_state.smooth_stretched=SMOOTH_MODE__UNKNOWN; hardware_img->source_state.smooth_stretched=SMOOTH_MODE__UNKNOWN;
hardware_img->source_state.smooth_shrunk=SMOOTH_MODE__UNKNOWN; hardware_img->source_state.smooth_shrunk=SMOOTH_MODE__UNKNOWN;
if (flags&NEW_HARDWARE_IMG__BUFFER_CONTENT){ if (flags&NEW_HARDWARE_IMG__BUFFER_CONTENT){
hardware_img->texture_handle=0; hardware_img->texture_handle=0;
if (flags&NEW_HARDWARE_IMG__DUPLICATE_PROVIDED_BUFFER){ if (flags&NEW_HARDWARE_IMG__DUPLICATE_PROVIDED_BUFFER){
hardware_img->software_pixel_buffer=NULL; hardware_img->software_pixel_buffer=NULL;
}else{ }else{
free(pixels);//the buffer was meant to be consumed, so we just free it immediately free(pixels);//the buffer was meant to be consumed, so we just free it immediately
hardware_img->software_pixel_buffer=NULL; 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;y<oy;y++){
NPO2_buffer[ox+nx*y]=NPO2_buffer[ox+nx*y-1];
}
}
//bottom row + 1 pixel for corner
if (oy!=ny){
for (int x=0;x<(ox+1);x++){
NPO2_buffer[nx*oy+x]=NPO2_buffer[nx*oy+x-nx];
}
}
//int maxtexsize;
//glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize);
//alert(maxtexsize);
//alert(nx);
//alert(ny);
*px=nx;
*py=ny;
return NPO2_buffer;
}
int32 new_texture_handle(){
GLuint texture=0;
glGenTextures(1,&texture);
return (int32)texture;
}
int32 new_hardware_img(int32 x, int32 y, uint32 *pixels, int32 flags){
//note: non power-of-2 dimensioned textures are supported on modern 3D cards and
// even on some older cards, as long as mip-mapping is not being used
// therefore, no attempt is made to convert the non-power-of-2 SCREEN sizes via software
// to avoid the performance hit this would incur
//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=(uint32*)malloc(x*y*4);
memcpy(hardware_img->software_pixel_buffer,pixels,x*y*4);
#ifdef QB64_ANDROID
//BGRA->RGBA
uint32 *pos=(uint32*)hardware_img->software_pixel_buffer;
int32 numPixels=x*y;
uint32 col;
while(numPixels--){
col=*pos;
*pos++= (col&0xFF00FF00) | ((col & 0xFF0000) >> 16) | ((col & 0x0000FF) << 16);
} }
#endif return handle;
}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; #else //end stubs
glerrorcode=glGetError();
if (glerrorcode){
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, x, y, GL_BGRA, GL_UNSIGNED_BYTE, pixels );
glerrorcode=glGetError(); int32 force_NPO2_fix=0;//This should only be set to 1 for debugging QB64
if (glerrorcode){
alert("gluBuild2DMipmaps failed"); uint32 *NPO2_buffer=(uint32*)malloc(4);
alert(glerrorcode); int32 NPO2_buffer_size_in_pixels=1;
}
hardware_img->source_state.PO2_fix=PO2_FIX__MIPMAPPED; uint32 *NPO2_texture_generate(int32 *px, int32 *py, uint32 *pixels){
hardware_img->PO2_w=x; int32 ox=*px;
hardware_img->PO2_h=y; 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;y<oy;y++){
NPO2_buffer[ox+nx*y]=NPO2_buffer[ox+nx*y-1];
}
}
//bottom row + 1 pixel for corner
if (oy!=ny){
for (int x=0;x<(ox+1);x++){
NPO2_buffer[nx*oy+x]=NPO2_buffer[nx*oy+x-nx];
}
}
//int maxtexsize;
//glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize);
//alert(maxtexsize);
//alert(nx);
//alert(ny);
*px=nx;
*py=ny;
return NPO2_buffer;
} }
set_render_source(INVALID_HARDWARE_HANDLE);
}
return handle; int32 new_texture_handle(){
} GLuint texture=0;
glGenTextures(1,&texture);
void hardware_img_buffer_to_texture(int32 handle){ return (int32)texture;
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);
hardware_img->software_pixel_buffer=NULL;//2015 critical bug fix
set_render_source(INVALID_HARDWARE_HANDLE); int32 new_hardware_img(int32 x, int32 y, uint32 *pixels, int32 flags){
} //note: non power-of-2 dimensioned textures are supported on modern 3D cards and
} // even on some older cards, as long as mip-mapping is not being used
// therefore, no attempt is made to convert the non-power-of-2 SCREEN sizes via software
void hardware_img_requires_depthbuffer(hardware_img_struct* hardware_img){ // to avoid the performance hit this would incur
if (hardware_img->depthbuffer_handle==0){ //create hardware img
//inspiration... http://www.opengl.org/wiki/Framebuffer_Object_Examples#Color_texture.2C_Depth_texture int32 handle;
static GLuint depth_tex; hardware_img_struct* hardware_img;
#ifndef QB64_GLES handle=list_add(hardware_img_handles);
glGenTextures(1, &depth_tex); hardware_img=(hardware_img_struct*)list_get(hardware_img_handles,handle);
glBindTexture(GL_TEXTURE_2D, depth_tex); hardware_img->w=x;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); hardware_img->h=y;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); hardware_img->dest_context_handle=0;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); hardware_img->depthbuffer_handle=0;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); hardware_img->pending_commands=0;
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); hardware_img->remove=0;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); hardware_img->alpha_disabled=0;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); hardware_img->depthbuffer_mode=DEPTHBUFFER_MODE__ON;
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, hardware_img->w, hardware_img->h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); hardware_img->valid=1;
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0/*mipmap level*/); hardware_img->source_state.PO2_fix=PO2_FIX__OFF;
#else hardware_img->source_state.texture_wrap=TEXTURE_WRAP_MODE__UNKNOWN;
glGenRenderbuffers(1, &depth_tex); hardware_img->source_state.smooth_stretched=SMOOTH_MODE__UNKNOWN;
glBindRenderbuffer(GL_RENDERBUFFER, depth_tex); hardware_img->source_state.smooth_shrunk=SMOOTH_MODE__UNKNOWN;
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, hardware_img->w, hardware_img->h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_tex); if (flags&NEW_HARDWARE_IMG__BUFFER_CONTENT){
#endif hardware_img->texture_handle=0;
//NULL means reserve texture memory, but texels are undefined if (flags&NEW_HARDWARE_IMG__DUPLICATE_PROVIDED_BUFFER){
glClear(GL_DEPTH_BUFFER_BIT); hardware_img->software_pixel_buffer=(uint32*)malloc(x*y*4);
hardware_img->depthbuffer_handle=depth_tex; memcpy(hardware_img->software_pixel_buffer,pixels,x*y*4);
set_render_source(INVALID_HARDWARE_HANDLE); #ifdef QB64_ANDROID
} //BGRA->RGBA
} uint32 *pos=(uint32*)hardware_img->software_pixel_buffer;
int32 numPixels=x*y;
uint32 col;
while(numPixels--){
col=*pos;
*pos++= (col&0xFF00FF00) | ((col & 0xFF0000) >> 16) | ((col & 0x0000FF) << 16);
}
#endif
}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);
hardware_img->software_pixel_buffer=NULL;//2015 critical bug fix
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;
#ifndef QB64_GLES
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);
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*/);
#else
glGenRenderbuffers(1, &depth_tex);
glBindRenderbuffer(GL_RENDERBUFFER, depth_tex);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, hardware_img->w, hardware_img->h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_tex);
#endif
//NULL means reserve texture memory, but texels are undefined
glClear(GL_DEPTH_BUFFER_BIT);
hardware_img->depthbuffer_handle=depth_tex;
set_render_source(INVALID_HARDWARE_HANDLE);
}
}
#endif #endif

View file

@ -1,80 +1,80 @@
#ifndef DEPENDENCY_PRINTER #ifndef DEPENDENCY_PRINTER
//stubs //stubs
void sub__printimage(int32 i){ void sub__printimage(int32 i){
return; 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); #else
dwNameLen=65536;
GetDefaultPrinter(szPrinterName,&dwNameLen); void sub__printimage(int32 i){
if((dc=CreateDC(TEXT("WINSPOOL"),szPrinterName,NULL,NULL))==NULL) goto failed;
ZeroMemory(&di,sizeof(DOCINFO)); #ifdef QB64_WINDOWS
di.cbSize=sizeof(DOCINFO);
di.lpszDocName=TEXT("Document"); static LPSTR szPrinterName=NULL;
if(StartDoc(dc,&di)<=0){DeleteDC(dc); goto failed;} DWORD dwNameLen;
if(StartPage(dc)<=0){EndDoc(dc); DeleteDC(dc); goto failed;} HDC dc;
DOCINFO di;
w=GetDeviceCaps(dc,HORZRES); uint32 w,h;
h=GetDeviceCaps(dc,VERTRES); int32 x,y;
int32 i2;
i2=func__newimage(w,h,32,1); BITMAPFILEHEADER bmfHeader;
if (i2==-1){EndDoc(dc); DeleteDC(dc); goto failed;} BITMAPINFOHEADER bi;
s2=&img[-i2]; img_struct *s,*s2;
sub__dontblend(i2,1);
sub__putimage(NULL,NULL,NULL,NULL,i,i2,NULL,NULL,NULL,NULL,8+32); if (i>=0){
validatepage(i); s=&img[page[i]];
ZeroMemory(&bi,sizeof(BITMAPINFOHEADER)); }else{
x=-i;
bi.biSize = sizeof(BITMAPINFOHEADER); if (x>=nextimg){error(258); return;}
bi.biWidth = w; s=&img[x];
bi.biHeight = h; if (!s->valid){error(258); return;}
bi.biPlanes = 1; }
bi.biBitCount = 32;
bi.biCompression = BI_RGB; if (!szPrinterName) szPrinterName=(LPSTR)malloc(65536);
bi.biSizeImage = 0; dwNameLen=65536;
bi.biXPelsPerMeter = 0; GetDefaultPrinter(szPrinterName,&dwNameLen);
bi.biYPelsPerMeter = 0; if((dc=CreateDC(TEXT("WINSPOOL"),szPrinterName,NULL,NULL))==NULL) goto failed;
bi.biClrUsed = 0; ZeroMemory(&di,sizeof(DOCINFO));
bi.biClrImportant = 0; di.cbSize=sizeof(DOCINFO);
di.lpszDocName=TEXT("Document");
for (y=0;y<h;y++){ if(StartDoc(dc,&di)<=0){DeleteDC(dc); goto failed;}
SetDIBitsToDevice(dc,0,y,w,1,0,0,0,1,s2->offset32+(y*w),(BITMAPINFO*)&bi, DIB_RGB_COLORS); 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;y<h;y++){
SetDIBitsToDevice(dc,0,y,w,1,0,0,0,1,s2->offset32+(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
} }
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 #endif

View file

@ -37,210 +37,210 @@
//#include <string.h> /* for strncpy */ //#include <string.h> /* for strncpy */
int32 _fmsbintoieee(float *src4, float *dest4) int32 _fmsbintoieee(float *src4, float *dest4)
{ {
unsigned char *msbin = (unsigned char *)src4; unsigned char *msbin = (unsigned char *)src4;
unsigned char *ieee = (unsigned char *)dest4; unsigned char *ieee = (unsigned char *)dest4;
unsigned char sign = 0x00; unsigned char sign = 0x00;
unsigned char ieee_exp = 0x00; unsigned char ieee_exp = 0x00;
int32 i; int32 i;
/* MS Binary Format */ /* MS Binary Format */
/* byte order => m3 | m2 | m1 | exponent */ /* byte order => m3 | m2 | m1 | exponent */
/* m1 is most significant byte => sbbb|bbbb */ /* m1 is most significant byte => sbbb|bbbb */
/* m3 is the least significant byte */ /* m3 is the least significant byte */
/* m = mantissa byte */ /* m = mantissa byte */
/* s = sign bit */ /* s = sign bit */
/* b = bit */ /* b = bit */
sign = msbin[2] & 0x80; /* 1000|0000b */ sign = msbin[2] & 0x80; /* 1000|0000b */
/* IEEE Single Precision Float Format */ /* IEEE Single Precision Float Format */
/* m3 m2 m1 exponent */ /* m3 m2 m1 exponent */
/* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee */ /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee */
/* s = sign bit */ /* s = sign bit */
/* e = exponent bit */ /* e = exponent bit */
/* m = mantissa bit */ /* m = mantissa bit */
for (i=0; i<4; i++) ieee[i] = 0; for (i=0; i<4; i++) ieee[i] = 0;
/* any msbin w/ exponent of zero = zero */ /* any msbin w/ exponent of zero = zero */
if (msbin[3] == 0) return 0; if (msbin[3] == 0) return 0;
ieee[3] |= sign; ieee[3] |= sign;
/* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places */ /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places */
/* the decimal point before the assumed bit, while */ /* the decimal point before the assumed bit, while */
/* IEEE places the decimal point after the assumed bit. */ /* IEEE places the decimal point after the assumed bit. */
ieee_exp = msbin[3] - 2; /* actually, msbin[3]-1-128+127 */ ieee_exp = msbin[3] - 2; /* actually, msbin[3]-1-128+127 */
/* the first 7 bits of the exponent in ieee[3] */ /* the first 7 bits of the exponent in ieee[3] */
ieee[3] |= ieee_exp >> 1; ieee[3] |= ieee_exp >> 1;
/* the one remaining bit in first bin of ieee[2] */ /* the one remaining bit in first bin of ieee[2] */
ieee[2] |= ieee_exp << 7; ieee[2] |= ieee_exp << 7;
/* 0111|1111b : mask out the msbin sign bit */ /* 0111|1111b : mask out the msbin sign bit */
ieee[2] |= msbin[2] & 0x7f; ieee[2] |= msbin[2] & 0x7f;
ieee[1] = msbin[1]; ieee[1] = msbin[1];
ieee[0] = msbin[0]; ieee[0] = msbin[0];
return 0; return 0;
} }
int32 _fieeetomsbin(float *src4, float *dest4) int32 _fieeetomsbin(float *src4, float *dest4)
{ {
unsigned char *ieee = (unsigned char *)src4; unsigned char *ieee = (unsigned char *)src4;
unsigned char *msbin = (unsigned char *)dest4; unsigned char *msbin = (unsigned char *)dest4;
unsigned char sign = 0x00; unsigned char sign = 0x00;
unsigned char msbin_exp = 0x00; unsigned char msbin_exp = 0x00;
int32 i; int32 i;
/* See _fmsbintoieee() for details of formats */ /* See _fmsbintoieee() for details of formats */
sign = ieee[3] & 0x80; sign = ieee[3] & 0x80;
msbin_exp |= ieee[3] << 1; msbin_exp |= ieee[3] << 1;
msbin_exp |= ieee[2] >> 7; msbin_exp |= ieee[2] >> 7;
/* An ieee exponent of 0xfe overflows in MBF */ /* An ieee exponent of 0xfe overflows in MBF */
if (msbin_exp == 0xfe) return 1; if (msbin_exp == 0xfe) return 1;
msbin_exp += 2; /* actually, -127 + 128 + 1 */ msbin_exp += 2; /* actually, -127 + 128 + 1 */
for (i=0; i<4; i++) msbin[i] = 0; for (i=0; i<4; i++) msbin[i] = 0;
msbin[3] = msbin_exp; msbin[3] = msbin_exp;
msbin[2] |= sign; msbin[2] |= sign;
msbin[2] |= ieee[2] & 0x7f; msbin[2] |= ieee[2] & 0x7f;
msbin[1] = ieee[1]; msbin[1] = ieee[1];
msbin[0] = ieee[0]; msbin[0] = ieee[0];
return 0; return 0;
} }
int32 _dmsbintoieee(double *src8, double *dest8) int32 _dmsbintoieee(double *src8, double *dest8)
{ {
unsigned char msbin[8]; unsigned char msbin[8];
unsigned char *ieee = (unsigned char *)dest8; unsigned char *ieee = (unsigned char *)dest8;
unsigned char sign = 0x00; unsigned char sign = 0x00;
uint32 ieee_exp = 0x0000; uint32 ieee_exp = 0x0000;
int32 i; int32 i;
/* A manipulatable copy of the msbin number */ /* A manipulatable copy of the msbin number */
memcpy(msbin,src8,8); //strncpy((char *)msbin,(char *)src8,8); memcpy(msbin,src8,8); //strncpy((char *)msbin,(char *)src8,8);
/* MS Binary Format */ /* MS Binary Format */
/* byte order => m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent */ /* byte order => m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent */
/* m1 is most significant byte => smmm|mmmm */ /* m1 is most significant byte => smmm|mmmm */
/* m7 is the least significant byte */ /* m7 is the least significant byte */
/* m = mantissa byte */ /* m = mantissa byte */
/* s = sign bit */ /* s = sign bit */
/* b = bit */ /* b = bit */
sign = msbin[6] & 0x80; /* 1000|0000b */ sign = msbin[6] & 0x80; /* 1000|0000b */
/* IEEE Single Precision Float Format */ /* IEEE Single Precision Float Format */
/* byte 8 byte 7 byte 6 byte 5 byte 4 and so on */ /* byte 8 byte 7 byte 6 byte 5 byte 4 and so on */
/* seee|eeee eeee|mmmm mmmm|mmmm mmmm|mmmm mmmm|mmmm ... */ /* seee|eeee eeee|mmmm mmmm|mmmm mmmm|mmmm mmmm|mmmm ... */
/* s = sign bit */ /* s = sign bit */
/* e = exponent bit */ /* e = exponent bit */
/* m = mantissa bit */ /* m = mantissa bit */
for (i=0; i<8; i++) ieee[i] = 0; for (i=0; i<8; i++) ieee[i] = 0;
/* any msbin w/ exponent of zero = zero */ /* any msbin w/ exponent of zero = zero */
if (msbin[7] == 0) return 0; if (msbin[7] == 0) return 0;
ieee[7] |= sign; ieee[7] |= sign;
/* MBF is bias 128 and IEEE is bias 1023. ALSO, MBF places */ /* MBF is bias 128 and IEEE is bias 1023. ALSO, MBF places */
/* the decimal point before the assumed bit, while */ /* the decimal point before the assumed bit, while */
/* IEEE places the decimal point after the assumed bit. */ /* IEEE places the decimal point after the assumed bit. */
ieee_exp = msbin[7] - 128 - 1 + 1023; ieee_exp = msbin[7] - 128 - 1 + 1023;
/* First 4 bits of the msbin exponent */ /* First 4 bits of the msbin exponent */
/* go into the last 4 bits of ieee[7] */ /* go into the last 4 bits of ieee[7] */
ieee[7] |= ieee_exp >> 4; ieee[7] |= ieee_exp >> 4;
/* The last 4 bits of msbin exponent */ /* The last 4 bits of msbin exponent */
/* go into the first 4 bits of ieee[6] */ /* go into the first 4 bits of ieee[6] */
ieee[6] |= ieee_exp << 4; ieee[6] |= ieee_exp << 4;
/* The msbin mantissa must be shifted to the right 1 bit. */ /* The msbin mantissa must be shifted to the right 1 bit. */
/* Remember that the msbin number has its bytes reversed. */ /* Remember that the msbin number has its bytes reversed. */
for (i=6; i>0; i--) for (i=6; i>0; i--)
{ {
msbin[i] <<= 1; msbin[i] <<= 1;
msbin[i] |= msbin[i-1] >> 7; msbin[i] |= msbin[i-1] >> 7;
} }
msbin[0] <<= 1; msbin[0] <<= 1;
/* Now the mantissa is put into the ieee array starting in */ /* Now the mantissa is put into the ieee array starting in */
/* the middle of the second to last byte. */ /* the middle of the second to last byte. */
for (i=6; i>0; i--) for (i=6; i>0; i--)
{ {
ieee[i] |= msbin[i] >> 4; ieee[i] |= msbin[i] >> 4;
ieee[i-1] |= msbin[i] << 4; ieee[i-1] |= msbin[i] << 4;
} }
ieee[0] |= msbin[0] >> 4; ieee[0] |= msbin[0] >> 4;
/* IEEE has a half byte less for its mantissa. If the msbin */ /* IEEE has a half byte less for its mantissa. If the msbin */
/* number has anything in this last half byte, then there is an */ /* number has anything in this last half byte, then there is an */
/* overflow. */ /* overflow. */
if (msbin[0] & 0x0f) if (msbin[0] & 0x0f)
return 1; return 1;
else else
return 0; return 0;
} }
int32 _dieeetomsbin(double *src8, double *dest8) int32 _dieeetomsbin(double *src8, double *dest8)
{ {
unsigned char ieee[8]; unsigned char ieee[8];
unsigned char *msbin = (unsigned char *)dest8; unsigned char *msbin = (unsigned char *)dest8;
unsigned char sign = 0x00; unsigned char sign = 0x00;
unsigned char any_on = 0x00; unsigned char any_on = 0x00;
uint32 msbin_exp = 0x0000; uint32 msbin_exp = 0x0000;
int32 i; int32 i;
/* Make a clobberable copy of the source number */ /* Make a clobberable copy of the source number */
memcpy(ieee,src8,8); //strncpy((char *)ieee,(char *)src8,8); memcpy(ieee,src8,8); //strncpy((char *)ieee,(char *)src8,8);
for (i=0; i<8; i++) msbin[i] = 0; for (i=0; i<8; i++) msbin[i] = 0;
/* If all are zero in src8, the msbin should be zero */ /* If all are zero in src8, the msbin should be zero */
for (i=0; i<8; i++) any_on |= ieee[i]; for (i=0; i<8; i++) any_on |= ieee[i];
if (!any_on) {return 0;} if (!any_on) {return 0;}
sign = ieee[7] & 0x80; sign = ieee[7] & 0x80;
msbin[6] |= sign; msbin[6] |= sign;
msbin_exp = (unsigned)(ieee[7] & 0x7f) * 0x10; msbin_exp = (unsigned)(ieee[7] & 0x7f) * 0x10;
msbin_exp += ieee[6] >> 4; msbin_exp += ieee[6] >> 4;
if (msbin_exp-0x3ff > 0x80) return 1; if (msbin_exp-0x3ff > 0x80) return 1;
msbin[7] = msbin_exp - 0x3ff + 0x80 + 1; msbin[7] = msbin_exp - 0x3ff + 0x80 + 1;
/* The ieee mantissa must be shifted up 3 bits */ /* The ieee mantissa must be shifted up 3 bits */
ieee[6] &= 0x0f; /* mask out the exponent in the second byte */ ieee[6] &= 0x0f; /* mask out the exponent in the second byte */
for (i=6; i>0; i--) for (i=6; i>0; i--)
{ {
msbin[i] |= ieee[i] << 3; msbin[i] |= ieee[i] << 3;
msbin[i] |= ieee[i-1] >> 5; msbin[i] |= ieee[i-1] >> 5;
} }
msbin[0] |= ieee[0] << 3; msbin[0] |= ieee[0] << 3;
return 0; return 0;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri1_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri1_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(y*dwidth+x2))=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)]; *(dst_offset32+(y*dwidth+x2))=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri1_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri1_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(y*dwidth+x1))=src_offset32[(ty>>16)*swidth+(tx>>16)]; *(dst_offset32+(y*dwidth+x1))=src_offset32[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri1_donerow; if(x1 > x2) goto mtri1_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,53 +143,53 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x1); pixel_offset32=dst_offset32+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(pixel_offset32++)=src_offset32[(ty>>16)*swidth+(tx>>16)]; *(pixel_offset32++)=src_offset32[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri1_donerow:; mtri1_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri1_final:; mtri1_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri1_usegrad3; goto mtri1_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri1s_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri1s_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(x2*dheight+y))=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)]; *(dst_offset32+(x2*dheight+y))=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri1s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1s_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri1s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1s_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(x1*dheight+y))=src_offset32[(ty>>16)*swidth+(tx>>16)]; *(dst_offset32+(x1*dheight+y))=src_offset32[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri1s_donerow; if(x1 > x2) goto mtri1s_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,54 +143,54 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x1*dheight+y); pixel_offset32=dst_offset32+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*pixel_offset32=src_offset32[(ty>>16)*swidth+(tx>>16)]; *pixel_offset32=src_offset32[(ty>>16)*swidth+(tx>>16)];
pixel_offset32+=dheight; pixel_offset32+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri1s_donerow:; mtri1s_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri1s_final:; mtri1s_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri1s_usegrad3; goto mtri1s_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri1t_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri1t_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(y*dwidth+x2))=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)]; *(dst_offset32+(y*dwidth+x2))=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri1t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1t_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri1t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1t_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(y*dwidth+x1))=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *(dst_offset32+(y*dwidth+x1))=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri1t_donerow; if(x1 > x2) goto mtri1t_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,53 +143,53 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x1); pixel_offset32=dst_offset32+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(pixel_offset32++)=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *(pixel_offset32++)=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri1t_donerow:; mtri1t_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri1t_final:; mtri1t_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri1t_usegrad3; goto mtri1t_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri1ts_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri1ts_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(x2*dheight+y))=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)]; *(dst_offset32+(x2*dheight+y))=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri1ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1ts_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri1ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri1ts_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset32+(x1*dheight+y))=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *(dst_offset32+(x1*dheight+y))=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri1ts_donerow; if(x1 > x2) goto mtri1ts_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,54 +143,54 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x1*dheight+y); pixel_offset32=dst_offset32+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*pixel_offset32=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *pixel_offset32=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
pixel_offset32+=dheight; pixel_offset32+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri1ts_donerow:; mtri1ts_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri1ts_final:; mtri1ts_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri1ts_usegrad3; goto mtri1ts_usegrad3;
} }

View file

@ -79,108 +79,108 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri2_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri2_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x2); pixel_offset32=dst_offset32+(y*dwidth+x2);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)])&0xFF000000){ switch((col=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri2_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri2_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x1); pixel_offset32=dst_offset32+(y*dwidth+x1);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){ switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri2_donerow; if(x1 > x2) goto mtri2_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -189,76 +189,76 @@ default:
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x1); pixel_offset32=dst_offset32+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){ switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
pixel_offset32++; pixel_offset32++;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri2_donerow:; mtri2_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri2_final:; mtri2_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri2_usegrad3; goto mtri2_usegrad3;
} }

View file

@ -79,108 +79,108 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri2s_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri2s_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x2*dheight+y); pixel_offset32=dst_offset32+(x2*dheight+y);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)])&0xFF000000){ switch((col=src_offset32[(g2ty>>16)*swidth+(g2tx>>16)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri2s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2s_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri2s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2s_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x1*dheight+y); pixel_offset32=dst_offset32+(x1*dheight+y);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){ switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri2s_donerow; if(x1 > x2) goto mtri2s_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -189,76 +189,76 @@ default:
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x1*dheight+y); pixel_offset32=dst_offset32+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){ switch((col=src_offset32[(ty>>16)*swidth+(tx>>16)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
pixel_offset32+=dheight; pixel_offset32+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri2s_donerow:; mtri2s_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri2s_final:; mtri2s_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri2s_usegrad3; goto mtri2s_usegrad3;
} }

View file

@ -79,108 +79,108 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri2t_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri2t_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x2); pixel_offset32=dst_offset32+(y*dwidth+x2);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)])&0xFF000000){ switch((col=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri2t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2t_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri2t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2t_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x1); pixel_offset32=dst_offset32+(y*dwidth+x1);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){ switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri2t_donerow; if(x1 > x2) goto mtri2t_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -189,76 +189,76 @@ default:
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(y*dwidth+x1); pixel_offset32=dst_offset32+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){ switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
pixel_offset32++; pixel_offset32++;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri2t_donerow:; mtri2t_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri2t_final:; mtri2t_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri2t_usegrad3; goto mtri2t_usegrad3;
} }

View file

@ -79,108 +79,108 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri2ts_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri2ts_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x2*dheight+y); pixel_offset32=dst_offset32+(x2*dheight+y);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)])&0xFF000000){ switch((col=src_offset32[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri2ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2ts_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri2ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri2ts_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x1*dheight+y); pixel_offset32=dst_offset32+(x1*dheight+y);
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){ switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri2ts_donerow; if(x1 > x2) goto mtri2ts_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -189,76 +189,76 @@ default:
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset32=dst_offset32+(x1*dheight+y); pixel_offset32=dst_offset32+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//--------plot pixel-------- //--------plot pixel--------
switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){ switch((col=src_offset32[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)])&0xFF000000){
case 0xFF000000: case 0xFF000000:
*pixel_offset32=col; *pixel_offset32=col;
break; break;
case 0x0: case 0x0:
break; break;
case 0x80000000: case 0x80000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend128[*pixel_offset32>>24]<<24);
break; break;
case 0x7F000000: case 0x7F000000:
*pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24); *pixel_offset32=(((*pixel_offset32&0xFEFEFE)+(col&0xFEFEFE))>>1)+(ablend127[*pixel_offset32>>24]<<24);
break; break;
default: default:
destcol=*pixel_offset32; destcol=*pixel_offset32;
cp=cblend+(col>>24<<16); cp=cblend+(col>>24<<16);
*pixel_offset32= *pixel_offset32=
cp[(col<<8&0xFF00)+(destcol&255) ] cp[(col<<8&0xFF00)+(destcol&255) ]
+(cp[(col&0xFF00) +(destcol>>8&255) ]<<8) +(cp[(col&0xFF00) +(destcol>>8&255) ]<<8)
+(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16) +(cp[(col>>8&0xFF00)+(destcol>>16&255)]<<16)
+(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24); +(ablend[(col>>24)+(destcol>>16&0xFF00)]<<24);
};//switch };//switch
//--------done plot pixel-------- //--------done plot pixel--------
pixel_offset32+=dheight; pixel_offset32+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri2ts_donerow:; mtri2ts_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri2ts_final:; mtri2ts_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri2ts_usegrad3; goto mtri2ts_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri3_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri3_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(y*dwidth+x2))=src_offset[(g2ty>>16)*swidth+(g2tx>>16)]; *(dst_offset+(y*dwidth+x2))=src_offset[(g2ty>>16)*swidth+(g2tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri3_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri3_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(y*dwidth+x1))=src_offset[(ty>>16)*swidth+(tx>>16)]; *(dst_offset+(y*dwidth+x1))=src_offset[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri3_donerow; if(x1 > x2) goto mtri3_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,53 +143,53 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(y*dwidth+x1); pixel_offset=dst_offset+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(pixel_offset++)=src_offset[(ty>>16)*swidth+(tx>>16)]; *(pixel_offset++)=src_offset[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri3_donerow:; mtri3_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri3_final:; mtri3_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri3_usegrad3; goto mtri3_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri3s_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri3s_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(x2*dheight+y))=src_offset[(g2ty>>16)*swidth+(g2tx>>16)]; *(dst_offset+(x2*dheight+y))=src_offset[(g2ty>>16)*swidth+(g2tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri3s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3s_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri3s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3s_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(x1*dheight+y))=src_offset[(ty>>16)*swidth+(tx>>16)]; *(dst_offset+(x1*dheight+y))=src_offset[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri3s_donerow; if(x1 > x2) goto mtri3s_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,54 +143,54 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(x1*dheight+y); pixel_offset=dst_offset+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*pixel_offset=src_offset[(ty>>16)*swidth+(tx>>16)]; *pixel_offset=src_offset[(ty>>16)*swidth+(tx>>16)];
pixel_offset+=dheight; pixel_offset+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri3s_donerow:; mtri3s_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri3s_final:; mtri3s_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri3s_usegrad3; goto mtri3s_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri3t_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri3t_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(y*dwidth+x2))=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)]; *(dst_offset+(y*dwidth+x2))=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri3t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3t_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri3t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3t_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(y*dwidth+x1))=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *(dst_offset+(y*dwidth+x1))=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri3t_donerow; if(x1 > x2) goto mtri3t_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,53 +143,53 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(y*dwidth+x1); pixel_offset=dst_offset+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(pixel_offset++)=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *(pixel_offset++)=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri3t_donerow:; mtri3t_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri3t_final:; mtri3t_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri3t_usegrad3; goto mtri3t_usegrad3;
} }

View file

@ -79,62 +79,62 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri3ts_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri3ts_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(x2*dheight+y))=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)]; *(dst_offset+(x2*dheight+y))=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri3ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3ts_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri3ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri3ts_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(x1*dheight+y))=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *(dst_offset+(x1*dheight+y))=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri3ts_donerow; if(x1 > x2) goto mtri3ts_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -143,54 +143,54 @@ for(y=y1;y<=y2;y++){
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(x1*dheight+y); pixel_offset=dst_offset+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*pixel_offset=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; *pixel_offset=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
pixel_offset+=dheight; pixel_offset+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri3ts_donerow:; mtri3ts_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri3ts_final:; mtri3ts_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri3ts_usegrad3; goto mtri3ts_usegrad3;
} }

View file

@ -79,64 +79,64 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri4_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri4_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[(g2ty>>16)*swidth+(g2tx>>16)]; col=src_offset[(g2ty>>16)*swidth+(g2tx>>16)];
if (col!=transparent_color) *(dst_offset+(y*dwidth+x2))=col; if (col!=transparent_color) *(dst_offset+(y*dwidth+x2))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri4_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri4_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[(ty>>16)*swidth+(tx>>16)]; col=src_offset[(ty>>16)*swidth+(tx>>16)];
if (col!=transparent_color) *(dst_offset+(y*dwidth+x1))=col; if (col!=transparent_color) *(dst_offset+(y*dwidth+x1))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri4_donerow; if(x1 > x2) goto mtri4_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -145,55 +145,55 @@ if (col!=transparent_color) *(dst_offset+(y*dwidth+x1))=col;
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(y*dwidth+x1); pixel_offset=dst_offset+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[(ty>>16)*swidth+(tx>>16)]; col=src_offset[(ty>>16)*swidth+(tx>>16)];
if (col!=transparent_color) *pixel_offset=col; if (col!=transparent_color) *pixel_offset=col;
pixel_offset++; pixel_offset++;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri4_donerow:; mtri4_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri4_final:; mtri4_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri4_usegrad3; goto mtri4_usegrad3;
} }

View file

@ -79,64 +79,64 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri4s_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri4s_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[(g2ty>>16)*swidth+(g2tx>>16)]; col=src_offset[(g2ty>>16)*swidth+(g2tx>>16)];
if (col!=transparent_color) *(dst_offset+(x2*dheight+y))=col; if (col!=transparent_color) *(dst_offset+(x2*dheight+y))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri4s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4s_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri4s_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4s_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[(ty>>16)*swidth+(tx>>16)]; col=src_offset[(ty>>16)*swidth+(tx>>16)];
if (col!=transparent_color) *(dst_offset+(x1*dheight+y))=col; if (col!=transparent_color) *(dst_offset+(x1*dheight+y))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri4s_donerow; if(x1 > x2) goto mtri4s_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -145,55 +145,55 @@ if (col!=transparent_color) *(dst_offset+(x1*dheight+y))=col;
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(x1*dheight+y); pixel_offset=dst_offset+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[(ty>>16)*swidth+(tx>>16)]; col=src_offset[(ty>>16)*swidth+(tx>>16)];
if (col!=transparent_color) *pixel_offset=col; if (col!=transparent_color) *pixel_offset=col;
pixel_offset+=dheight; pixel_offset+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri4s_donerow:; mtri4s_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri4s_final:; mtri4s_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri4s_usegrad3; goto mtri4s_usegrad3;
} }

View file

@ -79,64 +79,64 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri4t_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri4t_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)]; col=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)];
if (col!=transparent_color) *(dst_offset+(y*dwidth+x2))=col; if (col!=transparent_color) *(dst_offset+(y*dwidth+x2))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri4t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4t_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri4t_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4t_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
if (col!=transparent_color) *(dst_offset+(y*dwidth+x1))=col; if (col!=transparent_color) *(dst_offset+(y*dwidth+x1))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri4t_donerow; if(x1 > x2) goto mtri4t_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -145,55 +145,55 @@ if (col!=transparent_color) *(dst_offset+(y*dwidth+x1))=col;
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(y*dwidth+x1); pixel_offset=dst_offset+(y*dwidth+x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
if (col!=transparent_color) *pixel_offset=col; if (col!=transparent_color) *pixel_offset=col;
pixel_offset++; pixel_offset++;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri4t_donerow:; mtri4t_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri4t_final:; mtri4t_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri4t_usegrad3; goto mtri4t_usegrad3;
} }

View file

@ -79,64 +79,64 @@ g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck //2nd bottleneck
for(y=y1;y<=y2;y++){ for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536; if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri4ts_donerow; //crop if(entirely offscreen if(x1 >= dwidth | x2 < 0) goto mtri4ts_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty; tx = g1tx; ty = g1ty;
//calculate gradients if they might be required //calculate gradients if they might be required
if(x1 != x2){ if(x1 != x2){
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d; i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d; i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{ }else{
txi = 0; tyi = 0; txi = 0; tyi = 0;
} }
//calculate pixel offsets from ideals //calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768); roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is //draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)]; col=src_offset[((g2ty>>16)%sheight)*swidth+((g2tx>>16)%swidth)];
if (col!=transparent_color) *(dst_offset+(x2*dheight+y))=col; if (col!=transparent_color) *(dst_offset+(x2*dheight+y))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//move left one position //move left one position
x2--; x2--;
if(x1 > x2 | x2 < 0) goto mtri4ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4ts_donerow; //no more to do
}else{ }else{
if(no_edge_overlap){ if(no_edge_overlap){
x2 = x2 - 1; x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri4ts_donerow; //no more to do if(x1 > x2 | x2 < 0) goto mtri4ts_donerow; //no more to do
} }
} }
if(loff > 0){ if(loff > 0){
//draw lhs pixel as is //draw lhs pixel as is
if(x1 >= 0){ if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
if (col!=transparent_color) *(dst_offset+(x1*dheight+y))=col; if (col!=transparent_color) *(dst_offset+(x1*dheight+y))=col;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
} }
//skip to next x location, effectively reducing steps by 1 //skip to next x location, effectively reducing steps by 1
x1++; x1++;
if(x1 > x2) goto mtri4ts_donerow; if(x1 > x2) goto mtri4ts_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
} }
//align to loff //align to loff
i64 = -loff; i64 = -loff;
tx += (i64 * txi) / 65536; tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536; ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left if(x1 < 0){ //clip left
d = g2x - g1x; d = g2x - g1x;
i64 = g2tx - g1tx; i64 = g2tx - g1tx;
@ -145,55 +145,55 @@ if (col!=transparent_color) *(dst_offset+(x1*dheight+y))=col;
ty += ((i64 << 16) * -x1) / d; ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0; if(x1 < 0) x1 = 0;
} }
if(x2 >= dwidth){ if(x2 >= dwidth){
x2 = dwidth - 1; //clip right x2 = dwidth - 1; //clip right
} }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(x1*dheight+y); pixel_offset=dst_offset+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck //bottleneck
for(x=x1;x<=x2;x++){ for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)]; col=src_offset[((ty>>16)%sheight)*swidth+((tx>>16)%swidth)];
if (col!=transparent_color) *pixel_offset=col; if (col!=transparent_color) *pixel_offset=col;
pixel_offset+=dheight; pixel_offset+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi; tx += txi;
ty += tyi; ty += tyi;
} }
mtri4ts_donerow:; mtri4ts_donerow:;
if(y != y2){ if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi; g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi; g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
} }
} }
if(final == 0){ if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required //update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x; g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx; g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty; g1->ty = g1ty; g2->ty = g2ty;
mtri4ts_final:; mtri4ts_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen! if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3; if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice //avoid doing the same row twice
y1 = g3->y1 + 1; y1 = g3->y1 + 1;
y2 = g3->y2; y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi; g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi; g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1; final = 1;
goto mtri4ts_usegrad3; goto mtri4ts_usegrad3;
} }

View file

@ -3,21 +3,21 @@
//Note: Updated 15/7/2013: Switched to 223.27.25.123 because of DNS issues //Note: Updated 15/7/2013: Switched to 223.27.25.123 because of DNS issues
/* /*
PRINT whatismyip$ PRINT whatismyip$
$CHECKING:OFF $CHECKING:OFF
FUNCTION whatismyip$ FUNCTION whatismyip$
c = _OPENCLIENT("TCP/IP:80:www.qb64.net") c = _OPENCLIENT("TCP/IP:80:www.qb64.net")
IF c = 0 THEN EXIT FUNCTION IF c = 0 THEN EXIT FUNCTION
'send request 'send request
e$ = CHR$(13) + CHR$(10) e$ = CHR$(13) + CHR$(10)
x$ = "GET /ip.php HTTP/1.1" + e$ x$ = "GET /ip.php HTTP/1.1" + e$
x$ = x$ + "Host: www.qb64.net" + e$ x$ = x$ + "Host: www.qb64.net" + e$
x$ = x$ + "" + e$ x$ = x$ + "" + e$
PUT #c, , x$ PUT #c, , x$
'wait for reply 'wait for reply
t! = TIMER t! = TIMER
DO DO
IF TIMER - t! > 5 THEN CLOSE c: EXIT FUNCTION IF TIMER - t! > 5 THEN CLOSE c: EXIT FUNCTION
_DELAY 0.1 _DELAY 0.1
GET #c, , a2$ GET #c, , a2$
@ -25,185 +25,185 @@ DO
dots = 0 dots = 0
start = 0 start = 0
FOR x = 1 TO LEN(a$) FOR x = 1 TO LEN(a$)
a = ASC(a$, x) a = ASC(a$, x)
IF a >= 48 AND a <= 57 THEN IF a >= 48 AND a <= 57 THEN
IF start = 0 THEN start = x IF start = 0 THEN start = x
ELSE ELSE
IF a = 46 AND start <> 0 THEN IF a = 46 AND start <> 0 THEN
dots = dots + 1 dots = dots + 1
ELSE ELSE
IF dots = 3 THEN IF dots = 3 THEN
ip$ = MID$(a$, start, x - start) ip$ = MID$(a$, start, x - start)
EXIT DO EXIT DO
END IF END IF
start = 0: dots = 0 start = 0: dots = 0
END IF END IF
END IF END IF
NEXT NEXT
LOOP LOOP
CLOSE c CLOSE c
whatismyip$ = ip$ whatismyip$ = ip$
END FUNCTION END FUNCTION
$CHECKING:ON $CHECKING:ON
*/ */
qbs* WHATISMYIP(){ //changed name from FUNC_WHATISMYIP to WHATISMYIP qbs* WHATISMYIP(){ //changed name from FUNC_WHATISMYIP to WHATISMYIP
qbs *tqbs; qbs *tqbs;
ptrszint tmp_long; ptrszint tmp_long;
int32 tmp_fileno; int32 tmp_fileno;
uint32 qbs_tmp_base=qbs_tmp_list_nexti; uint32 qbs_tmp_base=qbs_tmp_list_nexti;
uint8 *tmp_mem_static_pointer=mem_static_pointer; uint8 *tmp_mem_static_pointer=mem_static_pointer;
uint32 tmp_cmem_sp=cmem_sp; uint32 tmp_cmem_sp=cmem_sp;
//data.txt //data.txt
qbs *_FUNC_WHATISMYIP_STRING_WHATISMYIP=NULL; qbs *_FUNC_WHATISMYIP_STRING_WHATISMYIP=NULL;
if (!_FUNC_WHATISMYIP_STRING_WHATISMYIP)_FUNC_WHATISMYIP_STRING_WHATISMYIP=qbs_new(0,0); if (!_FUNC_WHATISMYIP_STRING_WHATISMYIP)_FUNC_WHATISMYIP_STRING_WHATISMYIP=qbs_new(0,0);
float *_FUNC_WHATISMYIP_SINGLE_C=NULL; float *_FUNC_WHATISMYIP_SINGLE_C=NULL;
if(_FUNC_WHATISMYIP_SINGLE_C==NULL){ if(_FUNC_WHATISMYIP_SINGLE_C==NULL){
_FUNC_WHATISMYIP_SINGLE_C=(float*)mem_static_malloc(4); _FUNC_WHATISMYIP_SINGLE_C=(float*)mem_static_malloc(4);
*_FUNC_WHATISMYIP_SINGLE_C=0; *_FUNC_WHATISMYIP_SINGLE_C=0;
} }
qbs *_FUNC_WHATISMYIP_STRING_E=NULL; qbs *_FUNC_WHATISMYIP_STRING_E=NULL;
if (!_FUNC_WHATISMYIP_STRING_E)_FUNC_WHATISMYIP_STRING_E=qbs_new(0,0); if (!_FUNC_WHATISMYIP_STRING_E)_FUNC_WHATISMYIP_STRING_E=qbs_new(0,0);
qbs *_FUNC_WHATISMYIP_STRING_X=NULL; qbs *_FUNC_WHATISMYIP_STRING_X=NULL;
if (!_FUNC_WHATISMYIP_STRING_X)_FUNC_WHATISMYIP_STRING_X=qbs_new(0,0); if (!_FUNC_WHATISMYIP_STRING_X)_FUNC_WHATISMYIP_STRING_X=qbs_new(0,0);
byte_element_struct *byte_element_5276=NULL; byte_element_struct *byte_element_5276=NULL;
if (!byte_element_5276){ if (!byte_element_5276){
if ((mem_static_pointer+=12)<mem_static_limit) byte_element_5276=(byte_element_struct*)(mem_static_pointer-12); else byte_element_5276=(byte_element_struct*)mem_static_malloc(12); if ((mem_static_pointer+=12)<mem_static_limit) byte_element_5276=(byte_element_struct*)(mem_static_pointer-12); else byte_element_5276=(byte_element_struct*)mem_static_malloc(12);
} }
float *_FUNC_WHATISMYIP_SINGLE_T=NULL; float *_FUNC_WHATISMYIP_SINGLE_T=NULL;
if(_FUNC_WHATISMYIP_SINGLE_T==NULL){ if(_FUNC_WHATISMYIP_SINGLE_T==NULL){
_FUNC_WHATISMYIP_SINGLE_T=(float*)mem_static_malloc(4); _FUNC_WHATISMYIP_SINGLE_T=(float*)mem_static_malloc(4);
*_FUNC_WHATISMYIP_SINGLE_T=0; *_FUNC_WHATISMYIP_SINGLE_T=0;
} }
qbs *_FUNC_WHATISMYIP_STRING_A2=NULL; qbs *_FUNC_WHATISMYIP_STRING_A2=NULL;
if (!_FUNC_WHATISMYIP_STRING_A2)_FUNC_WHATISMYIP_STRING_A2=qbs_new(0,0); if (!_FUNC_WHATISMYIP_STRING_A2)_FUNC_WHATISMYIP_STRING_A2=qbs_new(0,0);
qbs *_FUNC_WHATISMYIP_STRING_A=NULL; qbs *_FUNC_WHATISMYIP_STRING_A=NULL;
if (!_FUNC_WHATISMYIP_STRING_A)_FUNC_WHATISMYIP_STRING_A=qbs_new(0,0); if (!_FUNC_WHATISMYIP_STRING_A)_FUNC_WHATISMYIP_STRING_A=qbs_new(0,0);
float *_FUNC_WHATISMYIP_SINGLE_DOTS=NULL; float *_FUNC_WHATISMYIP_SINGLE_DOTS=NULL;
if(_FUNC_WHATISMYIP_SINGLE_DOTS==NULL){ if(_FUNC_WHATISMYIP_SINGLE_DOTS==NULL){
_FUNC_WHATISMYIP_SINGLE_DOTS=(float*)mem_static_malloc(4); _FUNC_WHATISMYIP_SINGLE_DOTS=(float*)mem_static_malloc(4);
*_FUNC_WHATISMYIP_SINGLE_DOTS=0; *_FUNC_WHATISMYIP_SINGLE_DOTS=0;
} }
float *_FUNC_WHATISMYIP_SINGLE_START=NULL; float *_FUNC_WHATISMYIP_SINGLE_START=NULL;
if(_FUNC_WHATISMYIP_SINGLE_START==NULL){ if(_FUNC_WHATISMYIP_SINGLE_START==NULL){
_FUNC_WHATISMYIP_SINGLE_START=(float*)mem_static_malloc(4); _FUNC_WHATISMYIP_SINGLE_START=(float*)mem_static_malloc(4);
*_FUNC_WHATISMYIP_SINGLE_START=0; *_FUNC_WHATISMYIP_SINGLE_START=0;
} }
float *_FUNC_WHATISMYIP_SINGLE_X=NULL; float *_FUNC_WHATISMYIP_SINGLE_X=NULL;
if(_FUNC_WHATISMYIP_SINGLE_X==NULL){ if(_FUNC_WHATISMYIP_SINGLE_X==NULL){
_FUNC_WHATISMYIP_SINGLE_X=(float*)mem_static_malloc(4); _FUNC_WHATISMYIP_SINGLE_X=(float*)mem_static_malloc(4);
*_FUNC_WHATISMYIP_SINGLE_X=0; *_FUNC_WHATISMYIP_SINGLE_X=0;
} }
double fornext_value5279; double fornext_value5279;
double fornext_finalvalue5279; double fornext_finalvalue5279;
double fornext_step5279; double fornext_step5279;
uint8 fornext_step_negative5279; uint8 fornext_step_negative5279;
byte_element_struct *byte_element_5280=NULL; byte_element_struct *byte_element_5280=NULL;
if (!byte_element_5280){ if (!byte_element_5280){
if ((mem_static_pointer+=12)<mem_static_limit) byte_element_5280=(byte_element_struct*)(mem_static_pointer-12); else byte_element_5280=(byte_element_struct*)mem_static_malloc(12); if ((mem_static_pointer+=12)<mem_static_limit) byte_element_5280=(byte_element_struct*)(mem_static_pointer-12); else byte_element_5280=(byte_element_struct*)mem_static_malloc(12);
} }
float *_FUNC_WHATISMYIP_SINGLE_A=NULL; float *_FUNC_WHATISMYIP_SINGLE_A=NULL;
if(_FUNC_WHATISMYIP_SINGLE_A==NULL){ if(_FUNC_WHATISMYIP_SINGLE_A==NULL){
_FUNC_WHATISMYIP_SINGLE_A=(float*)mem_static_malloc(4); _FUNC_WHATISMYIP_SINGLE_A=(float*)mem_static_malloc(4);
*_FUNC_WHATISMYIP_SINGLE_A=0; *_FUNC_WHATISMYIP_SINGLE_A=0;
} }
qbs *_FUNC_WHATISMYIP_STRING_IP=NULL; qbs *_FUNC_WHATISMYIP_STRING_IP=NULL;
if (!_FUNC_WHATISMYIP_STRING_IP)_FUNC_WHATISMYIP_STRING_IP=qbs_new(0,0); if (!_FUNC_WHATISMYIP_STRING_IP)_FUNC_WHATISMYIP_STRING_IP=qbs_new(0,0);
if (new_error) goto exit_subfunc; if (new_error) goto exit_subfunc;
mem_lock *sf_mem_lock; mem_lock *sf_mem_lock;
new_mem_lock(); new_mem_lock();
sf_mem_lock=mem_lock_tmp; sf_mem_lock=mem_lock_tmp;
sf_mem_lock->type=3; sf_mem_lock->type=3;
*_FUNC_WHATISMYIP_SINGLE_C=func__openclient(qbs_new_txt_len("TCP/IP:80:www.qb64.net",22)); *_FUNC_WHATISMYIP_SINGLE_C=func__openclient(qbs_new_txt_len("TCP/IP:80:www.qb64.net",22));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
if ((-(*_FUNC_WHATISMYIP_SINGLE_C== 0 ))||new_error){ if ((-(*_FUNC_WHATISMYIP_SINGLE_C== 0 ))||new_error){
goto exit_subfunc; goto exit_subfunc;
} }
qbs_set(_FUNC_WHATISMYIP_STRING_E,qbs_add(func_chr( 13 ),func_chr( 10 ))); qbs_set(_FUNC_WHATISMYIP_STRING_E,qbs_add(func_chr( 13 ),func_chr( 10 )));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
qbs_set(_FUNC_WHATISMYIP_STRING_X,qbs_add(qbs_new_txt_len("GET /ip.php HTTP/1.1",20),_FUNC_WHATISMYIP_STRING_E)); qbs_set(_FUNC_WHATISMYIP_STRING_X,qbs_add(qbs_new_txt_len("GET /ip.php HTTP/1.1",20),_FUNC_WHATISMYIP_STRING_E));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
qbs_set(_FUNC_WHATISMYIP_STRING_X,qbs_add(qbs_add(_FUNC_WHATISMYIP_STRING_X,qbs_new_txt_len("Host: www.qb64.net",18)),_FUNC_WHATISMYIP_STRING_E)); qbs_set(_FUNC_WHATISMYIP_STRING_X,qbs_add(qbs_add(_FUNC_WHATISMYIP_STRING_X,qbs_new_txt_len("Host: www.qb64.net",18)),_FUNC_WHATISMYIP_STRING_E));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
qbs_set(_FUNC_WHATISMYIP_STRING_X,qbs_add(qbs_add(_FUNC_WHATISMYIP_STRING_X,qbs_new_txt_len("",0)),_FUNC_WHATISMYIP_STRING_E)); qbs_set(_FUNC_WHATISMYIP_STRING_X,qbs_add(qbs_add(_FUNC_WHATISMYIP_STRING_X,qbs_new_txt_len("",0)),_FUNC_WHATISMYIP_STRING_E));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
sub_put2(qbr(*_FUNC_WHATISMYIP_SINGLE_C),NULL,byte_element((uint64)_FUNC_WHATISMYIP_STRING_X->chr,_FUNC_WHATISMYIP_STRING_X->len,byte_element_5276),0); sub_put2(qbr(*_FUNC_WHATISMYIP_SINGLE_C),NULL,byte_element((uint64)_FUNC_WHATISMYIP_STRING_X->chr,_FUNC_WHATISMYIP_STRING_X->len,byte_element_5276),0);
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
*_FUNC_WHATISMYIP_SINGLE_T=func_timer(NULL,0); *_FUNC_WHATISMYIP_SINGLE_T=func_timer(NULL,0);
do{ do{
if ((-((func_timer(NULL,0)-*_FUNC_WHATISMYIP_SINGLE_T)>( 5 )))||new_error){ if ((-((func_timer(NULL,0)-*_FUNC_WHATISMYIP_SINGLE_T)>( 5 )))||new_error){
sub_close(qbr(*_FUNC_WHATISMYIP_SINGLE_C),1); sub_close(qbr(*_FUNC_WHATISMYIP_SINGLE_C),1);
goto exit_subfunc; goto exit_subfunc;
} }
sub__delay( 0.1E+0 ); sub__delay( 0.1E+0 );
sub_get2(qbr(*_FUNC_WHATISMYIP_SINGLE_C),NULL,_FUNC_WHATISMYIP_STRING_A2,0); sub_get2(qbr(*_FUNC_WHATISMYIP_SINGLE_C),NULL,_FUNC_WHATISMYIP_STRING_A2,0);
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
qbs_set(_FUNC_WHATISMYIP_STRING_A,qbs_add(_FUNC_WHATISMYIP_STRING_A,_FUNC_WHATISMYIP_STRING_A2)); qbs_set(_FUNC_WHATISMYIP_STRING_A,qbs_add(_FUNC_WHATISMYIP_STRING_A,_FUNC_WHATISMYIP_STRING_A2));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
*_FUNC_WHATISMYIP_SINGLE_DOTS= 0 ; *_FUNC_WHATISMYIP_SINGLE_DOTS= 0 ;
*_FUNC_WHATISMYIP_SINGLE_START= 0 ; *_FUNC_WHATISMYIP_SINGLE_START= 0 ;
fornext_value5279= 1 ; fornext_value5279= 1 ;
fornext_finalvalue5279=_FUNC_WHATISMYIP_STRING_A->len; fornext_finalvalue5279=_FUNC_WHATISMYIP_STRING_A->len;
fornext_step5279= 1 ; fornext_step5279= 1 ;
if (fornext_step5279<0) fornext_step_negative5279=1; else fornext_step_negative5279=0; if (fornext_step5279<0) fornext_step_negative5279=1; else fornext_step_negative5279=0;
if (new_error) goto fornext_error5279; if (new_error) goto fornext_error5279;
goto fornext_entrylabel5279; goto fornext_entrylabel5279;
while(1){ while(1){
fornext_value5279=fornext_step5279+(*_FUNC_WHATISMYIP_SINGLE_X); fornext_value5279=fornext_step5279+(*_FUNC_WHATISMYIP_SINGLE_X);
fornext_entrylabel5279: fornext_entrylabel5279:
*_FUNC_WHATISMYIP_SINGLE_X=fornext_value5279; *_FUNC_WHATISMYIP_SINGLE_X=fornext_value5279;
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
if (fornext_step_negative5279){ if (fornext_step_negative5279){
if (fornext_value5279<fornext_finalvalue5279) break; if (fornext_value5279<fornext_finalvalue5279) break;
}else{ }else{
if (fornext_value5279>fornext_finalvalue5279) break; if (fornext_value5279>fornext_finalvalue5279) break;
} }
fornext_error5279:; fornext_error5279:;
*_FUNC_WHATISMYIP_SINGLE_A=qbs_asc(_FUNC_WHATISMYIP_STRING_A,qbr(*_FUNC_WHATISMYIP_SINGLE_X)); *_FUNC_WHATISMYIP_SINGLE_A=qbs_asc(_FUNC_WHATISMYIP_STRING_A,qbr(*_FUNC_WHATISMYIP_SINGLE_X));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
if (((-(*_FUNC_WHATISMYIP_SINGLE_A>= 48 ))&(-(*_FUNC_WHATISMYIP_SINGLE_A<= 57 )))||new_error){ if (((-(*_FUNC_WHATISMYIP_SINGLE_A>= 48 ))&(-(*_FUNC_WHATISMYIP_SINGLE_A<= 57 )))||new_error){
if ((-(*_FUNC_WHATISMYIP_SINGLE_START== 0 ))||new_error){ if ((-(*_FUNC_WHATISMYIP_SINGLE_START== 0 ))||new_error){
*_FUNC_WHATISMYIP_SINGLE_START=*_FUNC_WHATISMYIP_SINGLE_X; *_FUNC_WHATISMYIP_SINGLE_START=*_FUNC_WHATISMYIP_SINGLE_X;
} }
}else{ }else{
if (((-(*_FUNC_WHATISMYIP_SINGLE_A== 46 ))&(-(*_FUNC_WHATISMYIP_SINGLE_START!= 0 )))||new_error){ if (((-(*_FUNC_WHATISMYIP_SINGLE_A== 46 ))&(-(*_FUNC_WHATISMYIP_SINGLE_START!= 0 )))||new_error){
*_FUNC_WHATISMYIP_SINGLE_DOTS=*_FUNC_WHATISMYIP_SINGLE_DOTS+ 1 ; *_FUNC_WHATISMYIP_SINGLE_DOTS=*_FUNC_WHATISMYIP_SINGLE_DOTS+ 1 ;
}else{ }else{
if ((-(*_FUNC_WHATISMYIP_SINGLE_DOTS== 3 ))||new_error){ if ((-(*_FUNC_WHATISMYIP_SINGLE_DOTS== 3 ))||new_error){
qbs_set(_FUNC_WHATISMYIP_STRING_IP,func_mid(_FUNC_WHATISMYIP_STRING_A,qbr(*_FUNC_WHATISMYIP_SINGLE_START),qbr(*_FUNC_WHATISMYIP_SINGLE_X-*_FUNC_WHATISMYIP_SINGLE_START),1)); qbs_set(_FUNC_WHATISMYIP_STRING_IP,func_mid(_FUNC_WHATISMYIP_STRING_A,qbr(*_FUNC_WHATISMYIP_SINGLE_START),qbr(*_FUNC_WHATISMYIP_SINGLE_X-*_FUNC_WHATISMYIP_SINGLE_START),1));
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
goto dl_exit_5277; goto dl_exit_5277;
} }
*_FUNC_WHATISMYIP_SINGLE_START= 0 ; *_FUNC_WHATISMYIP_SINGLE_START= 0 ;
*_FUNC_WHATISMYIP_SINGLE_DOTS= 0 ; *_FUNC_WHATISMYIP_SINGLE_DOTS= 0 ;
} }
} }
} }
fornext_exit_5278:; fornext_exit_5278:;
}while(1); }while(1);
dl_exit_5277:; dl_exit_5277:;
sub_close(qbr(*_FUNC_WHATISMYIP_SINGLE_C),1); sub_close(qbr(*_FUNC_WHATISMYIP_SINGLE_C),1);
qbs_set(_FUNC_WHATISMYIP_STRING_WHATISMYIP,_FUNC_WHATISMYIP_STRING_IP); qbs_set(_FUNC_WHATISMYIP_STRING_WHATISMYIP,_FUNC_WHATISMYIP_STRING_IP);
qbs_cleanup(qbs_tmp_base,0); qbs_cleanup(qbs_tmp_base,0);
exit_subfunc:; exit_subfunc:;
free_mem_lock(sf_mem_lock); free_mem_lock(sf_mem_lock);
//free.txt //free.txt
qbs_free(_FUNC_WHATISMYIP_STRING_E); qbs_free(_FUNC_WHATISMYIP_STRING_E);
qbs_free(_FUNC_WHATISMYIP_STRING_X); qbs_free(_FUNC_WHATISMYIP_STRING_X);
qbs_free(_FUNC_WHATISMYIP_STRING_A2); qbs_free(_FUNC_WHATISMYIP_STRING_A2);
qbs_free(_FUNC_WHATISMYIP_STRING_A); qbs_free(_FUNC_WHATISMYIP_STRING_A);
qbs_free(_FUNC_WHATISMYIP_STRING_IP); qbs_free(_FUNC_WHATISMYIP_STRING_IP);
if ((tmp_mem_static_pointer>=mem_static)&&(tmp_mem_static_pointer<=mem_static_limit)) mem_static_pointer=tmp_mem_static_pointer; else mem_static_pointer=mem_static; if ((tmp_mem_static_pointer>=mem_static)&&(tmp_mem_static_pointer<=mem_static_limit)) mem_static_pointer=tmp_mem_static_pointer; else mem_static_pointer=mem_static;
cmem_sp=tmp_cmem_sp; cmem_sp=tmp_cmem_sp;
qbs_maketmp(_FUNC_WHATISMYIP_STRING_WHATISMYIP);return _FUNC_WHATISMYIP_STRING_WHATISMYIP; qbs_maketmp(_FUNC_WHATISMYIP_STRING_WHATISMYIP);return _FUNC_WHATISMYIP_STRING_WHATISMYIP;
} }

View file

@ -1,78 +1,78 @@
/* Provide some OS/compiler macros. /* Provide some OS/compiler macros.
* QB64_WINDOWS: Is this a Windows system? * QB64_WINDOWS: Is this a Windows system?
* QB64_LINUX: Is this a Linux system? * QB64_LINUX: Is this a Linux system?
* QB64_MACOSX: Is this MacOSX, or MacOS or whatever Apple calls it now? * QB64_MACOSX: Is this MacOSX, or MacOS or whatever Apple calls it now?
* QB64_UNIX: Is this a Unix-flavoured system? * QB64_UNIX: Is this a Unix-flavoured system?
* *
* QB64_BACKSLASH_FILESYSTEM: Does this system use \ for file paths (as opposed to /)? * QB64_BACKSLASH_FILESYSTEM: Does this system use \ for file paths (as opposed to /)?
* QB64_MICROSOFT: Are we compiling with Visual Studio? * QB64_MICROSOFT: Are we compiling with Visual Studio?
* QB64_GCC: Are we compiling with gcc? * QB64_GCC: Are we compiling with gcc?
* QB64_MINGW: Are we compiling with MinGW, specifically? (Set in addition to QB64_GCC) * QB64_MINGW: Are we compiling with MinGW, specifically? (Set in addition to QB64_GCC)
* *
* QB64_32: A 32bit system (the default) * QB64_32: A 32bit system (the default)
* QB64_64: A 64bit system (assumes all Macs are 64 bit) * QB64_64: A 64bit system (assumes all Macs are 64 bit)
*/ */
#ifdef WIN32 #ifdef WIN32
#define QB64_WINDOWS #define QB64_WINDOWS
#define QB64_BACKSLASH_FILESYSTEM #define QB64_BACKSLASH_FILESYSTEM
#ifdef _MSC_VER #ifdef _MSC_VER
//Do we even support non-mingw compilers on Windows? //Do we even support non-mingw compilers on Windows?
#define QB64_MICROSOFT #define QB64_MICROSOFT
#else #else
#define QB64_GCC #define QB64_GCC
#define QB64_MINGW #define QB64_MINGW
#endif #endif
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define QB64_MACOSX #define QB64_MACOSX
#define QB64_UNIX #define QB64_UNIX
#define QB64_GCC #define QB64_GCC
#elif defined(__linux__) #elif defined(__linux__)
#define QB64_LINUX #define QB64_LINUX
#define QB64_UNIX #define QB64_UNIX
#define QB64_GCC #define QB64_GCC
#else #else
#error "Unknown system; refusing to build. Edit os.h if needed" #error "Unknown system; refusing to build. Edit os.h if needed"
#endif #endif
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(QB64_MACOSX) #if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(QB64_MACOSX)
#define QB64_64 #define QB64_64
#else #else
#define QB64_32 #define QB64_32
#endif #endif
/* common types (not quite an include guard, but allows an including /* common types (not quite an include guard, but allows an including
* file to not have these included. * file to not have these included.
* *
* Should this be adapted to check for each type before defining? * Should this be adapted to check for each type before defining?
*/ */
#ifndef QB64_OS_H_NO_TYPES #ifndef QB64_OS_H_NO_TYPES
#ifdef QB64_WINDOWS #ifdef QB64_WINDOWS
#define uint64 unsigned __int64 #define uint64 unsigned __int64
#define uint32 unsigned __int32 #define uint32 unsigned __int32
#define uint16 unsigned __int16 #define uint16 unsigned __int16
#define uint8 unsigned __int8 #define uint8 unsigned __int8
#define int64 __int64 #define int64 __int64
#define int32 __int32 #define int32 __int32
#define int16 __int16 #define int16 __int16
#define int8 __int8 #define int8 __int8
#else #else
#define int64 int64_t #define int64 int64_t
#define int32 int32_t #define int32 int32_t
#define int16 int16_t #define int16 int16_t
#define int8 int8_t #define int8 int8_t
#define uint64 uint64_t #define uint64 uint64_t
#define uint32 uint32_t #define uint32 uint32_t
#define uint16 uint16_t #define uint16 uint16_t
#define uint8 uint8_t #define uint8 uint8_t
#endif #endif
#ifdef QB64_64 #ifdef QB64_64
#define ptrszint int64 #define ptrszint int64
#define uptrszint uint64 #define uptrszint uint64
#define ptrsz 8 #define ptrsz 8
#else #else
#define ptrszint int32 #define ptrszint int32
#define uptrszint uint32 #define uptrszint uint32
#define ptrsz 4 #define ptrsz 4
#endif #endif
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/* Copyright (c) Robert Walker, support@tunesmithy.co.uk /* Copyright (c) Robert Walker, support@tunesmithy.co.uk
* Free source. Do what you wish with it - treat it as you would * Free source. Do what you wish with it - treat it as you would
* example code in a book on c programming. * example code in a book on c programming.
*/ */
#include "time64.h" #include "time64.h"
#undef time #undef time
#undef localtime #undef localtime
@ -16,196 +16,196 @@
#define SECS_TO_FT_MULT 10000000 #define SECS_TO_FT_MULT 10000000
#ifdef _DEBUG #ifdef _DEBUG
#define DEBUG_TIME_T #define DEBUG_TIME_T
#endif #endif
/* From MSVC help: /* From MSVC help:
* The gmtime, mktime, and localtime functions use the same single, * The gmtime, mktime, and localtime functions use the same single,
* statically allocated structure to hold their results. Each call to * statically allocated structure to hold their results. Each call to
* one of these functions destroys the result of any previous call. * one of these functions destroys the result of any previous call.
* If timer represents a date before midnight, January 1, 1970, * If timer represents a date before midnight, January 1, 1970,
* gmtime returns NULL. There is no error return. * gmtime returns NULL. There is no error return.
* *
* So here is the struct to use for our 64 bit implementation * So here is the struct to use for our 64 bit implementation
* *
* However, it may be useful to be able to make this thread safe * However, it may be useful to be able to make this thread safe
*/ */
#ifdef USE_THREAD_LOCAL_VARIABLES #ifdef USE_THREAD_LOCAL_VARIABLES
#define TIME64_THREAD_LOCAL _declspec(thread) #define TIME64_THREAD_LOCAL _declspec(thread)
#else #else
#define TIME64_THREAD_LOCAL #define TIME64_THREAD_LOCAL
#endif #endif
TIME64_THREAD_LOCAL static struct tm today_ret; TIME64_THREAD_LOCAL static struct tm today_ret;
static void T64ToFileTime(t64 *pt,FILETIME *pft) static void T64ToFileTime(t64 *pt,FILETIME *pft)
{ {
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart=*pt*SECS_TO_FT_MULT; li.QuadPart=*pt*SECS_TO_FT_MULT;
pft->dwLowDateTime=li.LowPart; pft->dwLowDateTime=li.LowPart;
pft->dwHighDateTime=li.HighPart; pft->dwHighDateTime=li.HighPart;
} }
static void FileTimeToT64(FILETIME *pft,t64 *pt) static void FileTimeToT64(FILETIME *pft,t64 *pt)
{ {
LARGE_INTEGER li; LARGE_INTEGER li;
li.LowPart = pft->dwLowDateTime; li.LowPart = pft->dwLowDateTime;
li.HighPart = pft->dwHighDateTime; li.HighPart = pft->dwHighDateTime;
*pt=li.QuadPart; *pt=li.QuadPart;
*pt/=SECS_TO_FT_MULT; *pt/=SECS_TO_FT_MULT;
} }
//#define FindTimeTBase() ((t64) 11644473600) //#define FindTimeTBase() ((t64) 11644473600)
#define FindTimeTBase() (((__int64)11644)*1000000+473600) #define FindTimeTBase() (((__int64)11644)*1000000+473600)
// calculated using // calculated using
/** /**
static t64 FindTimeTBase(void) static t64 FindTimeTBase(void)
{ {
// Find 1st Jan 1970 as a FILETIME // Find 1st Jan 1970 as a FILETIME
SYSTEMTIME st; SYSTEMTIME st;
FILETIME ft; FILETIME ft;
memset(&st,0,sizeof(st)); memset(&st,0,sizeof(st));
st.wYear=1970; st.wYear=1970;
st.wMonth=1; st.wMonth=1;
st.wDay=1; st.wDay=1;
SystemTimeToFileTime(&st, &ft); SystemTimeToFileTime(&st, &ft);
FileTimeToT64(&ft,&tbase); FileTimeToT64(&ft,&tbase);
return tbase; return tbase;
} }
**/ **/
static void SystemTimeToT64(SYSTEMTIME *pst,t64 *pt) static void SystemTimeToT64(SYSTEMTIME *pst,t64 *pt)
{ {
FILETIME ft; FILETIME ft;
SystemTimeToFileTime(pst, &ft); SystemTimeToFileTime(pst, &ft);
FileTimeToT64(&ft,pt); FileTimeToT64(&ft,pt);
*pt-=FindTimeTBase(); *pt-=FindTimeTBase();
} }
static void T64ToSystemTime(t64 *pt,SYSTEMTIME *pst) static void T64ToSystemTime(t64 *pt,SYSTEMTIME *pst)
{ {
FILETIME ft; FILETIME ft;
t64 t=*pt; t64 t=*pt;
t+=FindTimeTBase(); t+=FindTimeTBase();
T64ToFileTime(&t,&ft); T64ToFileTime(&t,&ft);
FileTimeToSystemTime(&ft,pst); FileTimeToSystemTime(&ft,pst);
} }
t64 time_64(t64 *pt) t64 time_64(t64 *pt)
{ {
t64 t; t64 t;
SYSTEMTIME st; SYSTEMTIME st;
GetSystemTime(&st); GetSystemTime(&st);
SystemTimeToT64(&st,&t); SystemTimeToT64(&st,&t);
#ifdef DEBUG_TIME_T #ifdef DEBUG_TIME_T
{ {
time_t t2=time(NULL); time_t t2=time(NULL);
if(t2>=0) if(t2>=0)
//2005 assert(abs(t2-(int)t)<=1); //2005 assert(abs(t2-(int)t)<=1);
assert(abs((long)(t2-(int)t))<=1); assert(abs((long)(t2-(int)t))<=1);
// the <=1 here is in case the seconds get incremented // the <=1 here is in case the seconds get incremented
// betweeen the GetSystemTime(..) call and the time(..) call // betweeen the GetSystemTime(..) call and the time(..) call
} }
#endif #endif
if(pt) if(pt)
*pt=t; *pt=t;
return t; return t;
} }
double difftime_64(t64 time1, t64 time0) double difftime_64(t64 time1, t64 time0)
{ {
return (double)(time1-time0); return (double)(time1-time0);
} }
t64 mktime64( struct tm *today ) t64 mktime64( struct tm *today )
{ {
t64 t; t64 t;
SYSTEMTIME st; SYSTEMTIME st;
st.wDay=(WORD)today->tm_mday; st.wDay=(WORD)today->tm_mday;
st.wDayOfWeek=(WORD)today->tm_wday; st.wDayOfWeek=(WORD)today->tm_wday;
st.wHour=(WORD)today->tm_hour; st.wHour=(WORD)today->tm_hour;
st.wMinute=(WORD)today->tm_min; st.wMinute=(WORD)today->tm_min;
st.wMonth=(WORD)(today->tm_mon+1); st.wMonth=(WORD)(today->tm_mon+1);
st.wSecond=(WORD)today->tm_sec; st.wSecond=(WORD)today->tm_sec;
st.wYear=(WORD)(today->tm_year+1900); st.wYear=(WORD)(today->tm_year+1900);
st.wMilliseconds=0; st.wMilliseconds=0;
SystemTimeToT64(&st,&t); SystemTimeToT64(&st,&t);
return t; return t;
} }
#define DAY_IN_SECS (60*60*24) #define DAY_IN_SECS (60*60*24)
struct tm *gmtime_64(t64 t) struct tm *gmtime_64(t64 t)
{ {
SYSTEMTIME st; SYSTEMTIME st;
T64ToSystemTime(&t,&st); T64ToSystemTime(&t,&st);
today_ret.tm_wday=st.wDayOfWeek; today_ret.tm_wday=st.wDayOfWeek;
today_ret.tm_min=st.wMinute; today_ret.tm_min=st.wMinute;
today_ret.tm_sec=st.wSecond; today_ret.tm_sec=st.wSecond;
today_ret.tm_mon=st.wMonth-1; today_ret.tm_mon=st.wMonth-1;
today_ret.tm_mday=st.wDay; today_ret.tm_mday=st.wDay;
today_ret.tm_hour=st.wHour; today_ret.tm_hour=st.wHour;
today_ret.tm_year=st.wYear-1900; today_ret.tm_year=st.wYear-1900;
{ {
SYSTEMTIME styear; SYSTEMTIME styear;
t64 t64Year; t64 t64Year;
memset(&styear,0,sizeof(styear)); memset(&styear,0,sizeof(styear));
styear.wYear=st.wYear; styear.wYear=st.wYear;
styear.wMonth=1; styear.wMonth=1;
styear.wDay=1; styear.wDay=1;
SystemTimeToT64(&styear,&t64Year); SystemTimeToT64(&styear,&t64Year);
today_ret.tm_yday=(int)((t-t64Year)/DAY_IN_SECS); today_ret.tm_yday=(int)((t-t64Year)/DAY_IN_SECS);
} }
today_ret.tm_isdst=0; today_ret.tm_isdst=0;
#ifdef DEBUG_TIME_T #ifdef DEBUG_TIME_T
{ {
struct tm today2; struct tm today2;
long t32=(int)t; long t32=(int)t;
if(t32>=0) if(t32>=0)
{ {
//2005 today2=*gmtime(&t32); //2005 today2=*gmtime(&t32);
today2=*gmtime((time_t*)&t32); today2=*gmtime((time_t*)&t32);
assert(today_ret.tm_yday==today2.tm_yday); assert(today_ret.tm_yday==today2.tm_yday);
assert(today_ret.tm_wday==today2.tm_wday); assert(today_ret.tm_wday==today2.tm_wday);
assert(today_ret.tm_min==today2.tm_min); assert(today_ret.tm_min==today2.tm_min);
assert(today_ret.tm_sec==today2.tm_sec); assert(today_ret.tm_sec==today2.tm_sec);
assert(today_ret.tm_mon==today2.tm_mon); assert(today_ret.tm_mon==today2.tm_mon);
assert(today_ret.tm_mday==today2.tm_mday); assert(today_ret.tm_mday==today2.tm_mday);
assert(today_ret.tm_hour==today2.tm_hour); assert(today_ret.tm_hour==today2.tm_hour);
assert(today_ret.tm_year==today2.tm_year); assert(today_ret.tm_year==today2.tm_year);
} }
} }
{ {
t64 t2=mktime64(&today_ret); t64 t2=mktime64(&today_ret);
assert(t2==t); assert(t2==t);
} }
#endif #endif
return &today_ret; return &today_ret;
} }
struct tm *localtime_64(t64 *pt) struct tm *localtime_64(t64 *pt)
{ {
t64 t=*pt; t64 t=*pt;
FILETIME ft,ftlocal; FILETIME ft,ftlocal;
T64ToFileTime(&t,&ft); T64ToFileTime(&t,&ft);
FileTimeToLocalFileTime(&ft,&ftlocal); FileTimeToLocalFileTime(&ft,&ftlocal);
FileTimeToT64(&ftlocal,&t); FileTimeToT64(&ftlocal,&t);
today_ret=*gmtime_64(t); today_ret=*gmtime_64(t);
{ {
TIME_ZONE_INFORMATION TimeZoneInformation; TIME_ZONE_INFORMATION TimeZoneInformation;
switch(GetTimeZoneInformation(&TimeZoneInformation)) switch(GetTimeZoneInformation(&TimeZoneInformation))
{ {
case TIME_ZONE_ID_DAYLIGHT:today_ret.tm_isdst=1;break; case TIME_ZONE_ID_DAYLIGHT:today_ret.tm_isdst=1;break;
case TIME_ZONE_ID_STANDARD:today_ret.tm_isdst=0;break; case TIME_ZONE_ID_STANDARD:today_ret.tm_isdst=0;break;
case TIME_ZONE_ID_UNKNOWN:today_ret.tm_isdst=-1;break; case TIME_ZONE_ID_UNKNOWN:today_ret.tm_isdst=-1;break;
} }
} }
return &today_ret; return &today_ret;
} }

View file

@ -1,54 +1,54 @@
/* Copyright (c) Robert Walker, support@tunesmithy.co.uk /* Copyright (c) Robert Walker, support@tunesmithy.co.uk
* Free source. Do what you wish with it - treat it as you would * Free source. Do what you wish with it - treat it as you would
* example code in a book on c programming. * example code in a book on c programming.
*/ */
/* Note /* Note
* When you include this header then all your time_t variables will become * When you include this header then all your time_t variables will become
* __int64 variables. * __int64 variables.
* *
* Be sure to check that routines that use them work with __int64 variables. * Be sure to check that routines that use them work with __int64 variables.
* By way of example, if you use sprintf, fprintf, sscanf, fscanf etc * By way of example, if you use sprintf, fprintf, sscanf, fscanf etc
* then you won't be able to use the %d format field for these variables * then you won't be able to use the %d format field for these variables
* in a 32 bit build - they will overflow and be used for the next format field * in a 32 bit build - they will overflow and be used for the next format field
* as well. Instead convert your variables to unsigned ints and use %lu * as well. Instead convert your variables to unsigned ints and use %lu
* *
* e.g. * e.g.
* sprintf(sz,"time_saved %lu secs",(UINT)time(NULL)); * sprintf(sz,"time_saved %lu secs",(UINT)time(NULL));
* *
* { * {
* time_t time_saved=0; * time_t time_saved=0;
* UINT utime_saved=0; * UINT utime_saved=0;
* sscanf( sz, "%*s%lu", &utime_saved); * sscanf( sz, "%*s%lu", &utime_saved);
* // read it in as an unsigned long as sscanf can't read to __int64 variables * // read it in as an unsigned long as sscanf can't read to __int64 variables
* // directly * // directly
* time_saved=utime_saved; * time_saved=utime_saved;
* } * }
* *
* Unsigned ints are fine for dates until beyond the end of this century * Unsigned ints are fine for dates until beyond the end of this century
* *
* If your compiler has some other type of native 64 bit type then * If your compiler has some other type of native 64 bit type then
* change the line typedef __int64 t64 * change the line typedef __int64 t64
*/ */
#include <time.h> #include <time.h>
/* /*
* Note. I think the usual time functions aren't thread safe becuase they use * Note. I think the usual time functions aren't thread safe becuase they use
* a single struct for localtime, gmtime and mktime. Several threads * a single struct for localtime, gmtime and mktime. Several threads
* might access that same structure simultaneously. * might access that same structure simultaneously.
* *
* However we can make this implementation thread safe using thread local * However we can make this implementation thread safe using thread local
* variables if we so wish - simply define the tm struct that they * variables if we so wish - simply define the tm struct that they
* return to be thread local. But - I'm not sure if the pointer you get * return to be thread local. But - I'm not sure if the pointer you get
* back from localtime can be kept for any length of time with thread * back from localtime can be kept for any length of time with thread
* local variables. Can the address for it change?? Anyone know? * local variables. Can the address for it change?? Anyone know?
* *
* You can't use this method with DLLs that might be loaded using LoadLibrary * You can't use this method with DLLs that might be loaded using LoadLibrary
* - see * - see
* http://msdn.microsoft.com/library/en-us/dllproc/base/dynamic_link_library_data.asp * http://msdn.microsoft.com/library/en-us/dllproc/base/dynamic_link_library_data.asp
*/ */
// #define USE_THREAD_LOCAL_VARIABLES // #define USE_THREAD_LOCAL_VARIABLES
@ -73,11 +73,11 @@ t64 mktime64( struct tm *today );
struct tm *gmtime_64(t64 t); struct tm *gmtime_64(t64 t);
/* allow multiple inclusion of this file - does no harm, and we want /* allow multiple inclusion of this file - does no harm, and we want
* the last one to be effective if included several times * the last one to be effective if included several times
* as in * as in
* #include "time64.h" * #include "time64.h"
* ... * ...
* #include <time.h> * #include <time.h>
* ... * ...
* #include "time64.h" * #include "time64.h"
*/ */