README: explain further musl-specific tweaks
[rofl0r-df-libgraphics.git] / g_src / enabler.h
blob086390c59b7583e8d08959c25635c608898d5be9
1 //some of this stuff is based on public domain code from nehe or opengl books over the years
2 //additions and modifications Copyright (c) 2008, Tarn Adams
3 //All rights reserved. See game.cpp or license.txt for more information.
5 #ifndef ENABLER_H
6 #define ENABLER_H
8 #include "platform.h"
9 #include <stdint.h>
10 #include <SDL/SDL.h>
11 #include <SDL/SDL_thread.h>
12 #ifdef __APPLE__
13 # include <SDL_ttf/SDL_ttf.h>
14 # include <SDL_image/SDL_image.h>
15 #else
16 # include <SDL/SDL_ttf.h>
17 # include <SDL/SDL_image.h>
18 #endif
20 #ifdef WANT_GL
21 #include "GL/glew.h"
22 #endif
24 #include <map>
25 #include <vector>
26 #include <algorithm>
27 #include <utility>
28 #include <list>
29 #include <iostream>
30 #include <sstream>
31 #include <stack>
32 #include <queue>
33 #include <set>
34 #include <functional>
36 using std::vector;
37 using std::pair;
38 using std::map;
39 using std::set;
40 using std::list;
41 using std::stack;
42 using std::queue;
44 #include "basics.h"
45 #include "svector.h"
46 #include "endian.h"
47 #include "files.h"
48 #include "enabler_input.h"
49 #include "mail.hpp"
51 #define ENABLER
53 #ifndef BITS
55 #define BITS
57 #define BIT1 1
58 #define BIT2 2
59 #define BIT3 4
60 #define BIT4 8
61 #define BIT5 16
62 #define BIT6 32
63 #define BIT7 64
64 #define BIT8 128
65 #define BIT9 256
66 #define BIT10 512
67 #define BIT11 1024
68 #define BIT12 2048
69 #define BIT13 4096
70 #define BIT14 8192
71 #define BIT15 16384
72 #define BIT16 32768
73 #define BIT17 65536UL
74 #define BIT18 131072UL
75 #define BIT19 262144UL
76 #define BIT20 524288UL
77 #define BIT21 1048576UL
78 #define BIT22 2097152UL
79 #define BIT23 4194304UL
80 #define BIT24 8388608UL
81 #define BIT25 16777216UL
82 #define BIT26 33554432UL
83 #define BIT27 67108864UL
84 #define BIT28 134217728UL
85 #define BIT29 268435456UL
86 #define BIT30 536870912UL
87 #define BIT31 1073741824UL
88 #define BIT32 2147483648UL
90 #endif
92 #define GAME_TITLE_STRING "Dwarf Fortress"
94 char get_slot_and_addbit_uchar(unsigned char &addbit,long &slot,long checkflag,long slotnum);
96 class pstringst
98 public:
99 string dat;
102 class stringvectst
104 public:
105 svector<pstringst *> str;
107 void add_string(const string &st)
109 pstringst *newp=new pstringst;
110 newp->dat=st;
111 str.push_back(newp);
114 long add_unique_string(const string &st)
116 long i;
117 for(i=(long)str.size()-1;i>=0;i--)
119 if(str[i]->dat==st)return i;
121 add_string(st);
122 return (long)str.size()-1;
125 void add_string(const char *st)
127 if(st!=NULL)
129 pstringst *newp=new pstringst;
130 newp->dat=st;
131 str.push_back(newp);
135 void insert_string(long k,const string &st)
137 pstringst *newp=new pstringst;
138 newp->dat=st;
139 if(str.size()>k)str.insert(k,newp);
140 else str.push_back(newp);
143 ~stringvectst()
145 clean();
148 void clean()
150 while(str.size()>0)
152 delete str[0];
153 str.erase(0);
157 void read_file(file_compressorst &filecomp,long loadversion)
159 long dummy;
160 filecomp.read_file(dummy);
161 str.resize(dummy);
163 long s;
164 for(s=0;s<dummy;s++)
166 str[s]=new pstringst;
167 filecomp.read_file(str[s]->dat);
170 void write_file(file_compressorst &filecomp)
172 long dummy=str.size();
173 filecomp.write_file(dummy);
175 long s;
176 for(s=0;s<dummy;s++)
178 filecomp.write_file(str[s]->dat);
182 void copy_from(stringvectst &src)
184 clean();
186 str.resize(src.str.size());
188 long s;
189 for(s=(long)src.str.size()-1;s>=0;s--)
191 str[s]=new pstringst;
192 str[s]->dat=src.str[s]->dat;
196 bool has_string(const string &st)
198 long i;
199 for(i=(long)str.size()-1;i>=0;i--)
201 if(str[i]->dat==st)return true;
203 return false;
206 void remove_string(const string &st)
208 long i;
209 for(i=(long)str.size()-1;i>=0;i--)
211 if(str[i]->dat==st)
213 delete str[i];
214 str.erase(i);
219 void operator=(stringvectst &two);
222 class flagarrayst
224 public:
225 flagarrayst()
227 slotnum=0;
228 array=NULL;
230 ~flagarrayst()
232 if(array!=NULL)delete[] array;
233 array=NULL;
234 slotnum=0;
237 void set_size_on_flag_num(long flagnum)
239 if(flagnum<=0)return;
241 set_size(((flagnum-1)>>3)+1);
244 void set_size(long newsize)
246 if(newsize<=0)return;
248 if(array!=NULL)delete[] array;
249 array=new unsigned char[newsize];
250 memset(array,0,sizeof(unsigned char)*newsize);
252 slotnum=newsize;
255 void clear_all()
257 if(slotnum<=0)return;
259 if(array!=NULL)memset(array,0,sizeof(unsigned char)*slotnum);
262 void copy_from(flagarrayst &src)
264 clear_all();
266 if(src.slotnum>0)
268 set_size(src.slotnum);
269 memmove(array,src.array,sizeof(unsigned char)*slotnum);
273 bool has_flag(long checkflag)
275 long slot;
276 unsigned char addbit;
277 if(get_slot_and_addbit_uchar(addbit,slot,checkflag,slotnum))
279 return (array[slot]&addbit)!=0;
281 else return false;
284 void add_flag(long checkflag)
286 long slot;
287 unsigned char addbit;
288 if(get_slot_and_addbit_uchar(addbit,slot,checkflag,slotnum))
290 array[slot]|=addbit;
294 void toggle_flag(long checkflag)
296 long slot;
297 unsigned char addbit;
298 if(get_slot_and_addbit_uchar(addbit,slot,checkflag,slotnum))
300 array[slot]^=addbit;
304 void remove_flag(long checkflag)
306 long slot;
307 unsigned char addbit;
308 if(get_slot_and_addbit_uchar(addbit,slot,checkflag,slotnum))
310 array[slot]&=~addbit;
314 void write_file(file_compressorst &filecomp)
316 filecomp.write_file(slotnum);
317 if(slotnum>0)
319 long ind;
320 for(ind=0;ind<slotnum;ind++)filecomp.write_file(array[ind]);
324 void read_file(file_compressorst &filecomp,long loadversion)
326 long newsl;
327 filecomp.read_file(newsl);
328 if(newsl>0)
330 //AVOID UNNECESSARY DELETE/NEW
331 if(array!=NULL&&slotnum!=newsl)
333 delete[] array;
334 array=new unsigned char[newsl];
336 if(array==NULL)array=new unsigned char[newsl];
338 long ind;
339 for(ind=0;ind<newsl;ind++)filecomp.read_file(array[ind]);
341 slotnum=newsl;
343 else if(array!=NULL)
345 delete[] array;
346 array=NULL;
350 private:
351 unsigned char *array;
352 long slotnum;
355 #ifdef ENABLER
357 #define COLOR_BLACK 0
358 #define COLOR_BLUE 1
359 #define COLOR_GREEN 2
360 #define COLOR_CYAN 3
361 #define COLOR_RED 4
362 #define COLOR_MAGENTA 5
363 #define COLOR_YELLOW 6
364 #define COLOR_WHITE 7
366 enum ColorData
368 COLOR_DATA_WHITE_R,
369 COLOR_DATA_WHITE_G,
370 COLOR_DATA_WHITE_B,
371 COLOR_DATA_RED_R,
372 COLOR_DATA_RED_G,
373 COLOR_DATA_RED_B,
374 COLOR_DATA_GREEN_R,
375 COLOR_DATA_GREEN_G,
376 COLOR_DATA_GREEN_B,
377 COLOR_DATA_BLUE_R,
378 COLOR_DATA_BLUE_G,
379 COLOR_DATA_BLUE_B,
380 COLOR_DATA_YELLOW_R,
381 COLOR_DATA_YELLOW_G,
382 COLOR_DATA_YELLOW_B,
383 COLOR_DATA_MAGENTA_R,
384 COLOR_DATA_MAGENTA_G,
385 COLOR_DATA_MAGENTA_B,
386 COLOR_DATA_CYAN_R,
387 COLOR_DATA_CYAN_G,
388 COLOR_DATA_CYAN_B,
389 COLOR_DATANUM
392 #define TILEFLAG_DEAD BIT1
393 #define TILEFLAG_ROTATE BIT2
394 #define TILEFLAG_PIXRECT BIT3
395 #define TILEFLAG_HORFLIP BIT4
396 #define TILEFLAG_VERFLIP BIT5
397 #define TILEFLAG_LINE BIT6
398 #define TILEFLAG_RECT BIT7
399 #define TILEFLAG_BUFFER_DRAW BIT8
400 #define TILEFLAG_MODEL_PERSPECTIVE BIT9
401 #define TILEFLAG_MODEL_ORTHO BIT10
402 #define TILEFLAG_MODEL_TRANSLATE BIT11
403 #define TILEFLAG_LINE_3D BIT12
405 #define TRIMAX 9999
407 enum render_phase {
408 setup, // 0
409 complete,
410 phase_count
412 #ifdef WANT_GL
413 class texture_bo {
414 GLuint bo, tbo;
415 public:
416 texture_bo() { bo = tbo = 0; }
417 void reset() {
418 if (bo) {
419 glDeleteBuffers(1, &bo);
420 glDeleteTextures(1, &tbo);
421 bo = tbo = 0;
422 printGLError();
425 void buffer(GLvoid *ptr, GLsizeiptr sz) {
426 if (bo) reset();
427 glGenBuffersARB(1, &bo);
428 glGenTextures(1, &tbo);
429 glBindBufferARB(GL_TEXTURE_BUFFER_ARB, bo);
430 glBufferDataARB(GL_TEXTURE_BUFFER_ARB, sz, ptr, GL_STATIC_DRAW_ARB);
431 printGLError();
433 void bind(GLenum texture_unit, GLenum type) {
434 glActiveTexture(texture_unit);
435 glBindTexture(GL_TEXTURE_BUFFER_ARB, tbo);
436 glTexBufferARB(GL_TEXTURE_BUFFER_ARB, type, bo);
437 printGLError();
439 GLuint texnum() { return tbo; }
443 class shader {
444 string filename;
445 std::ostringstream lines;
446 public:
447 std::ostringstream header;
448 void load(const string &filename) {
449 this->filename = filename;
450 std::ifstream file(filename.c_str());
451 string version;
452 getline(file, version);
453 header << version << std::endl;
454 while (file.good()) {
455 string line;
456 getline(file, line);
457 lines << line << std::endl;
459 file.close();
461 GLuint upload(GLenum type) {
462 GLuint shader = glCreateShader(type);
463 string lines_done = lines.str(), header_done = header.str();
464 const char *ptrs[3];
465 ptrs[0] = header_done.c_str();
466 ptrs[1] = "#line 1 0\n";
467 ptrs[2] = lines_done.c_str();
468 glShaderSource(shader, 3, ptrs, NULL);
469 glCompileShader(shader);
470 // Let's see if this compiled correctly..
471 GLint status;
472 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
473 if (status == GL_FALSE) { // ..no. Check the compilation log.
474 GLint log_size;
475 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_size);
476 //errorlog << filename << " preprocessed source:" << std::endl;
477 std::cerr << filename << " preprocessed source:" << std::endl;
478 //errorlog << header_done << "#line 1 0\n" << lines_done;
479 std::cerr << header_done << "#line 1 0\n" << lines_done;
480 //errorlog << filename << " shader compilation log (" << log_size << "):" << std::endl;
481 std::cerr << filename << " shader compilation log (" << log_size << "):" << std::endl;
482 char *buf = new char[log_size];
483 glGetShaderInfoLog(shader, log_size, NULL, buf);
484 //errorlog << buf << std::endl;
485 std::cerr << buf << std::endl;
486 //errorlog.flush();
487 delete[] buf;
488 MessageBox(NULL, "Shader compilation failed; details in errorlog.txt", "Critical error", MB_OK);
489 abort();
491 printGLError();
492 return shader;
495 #endif
497 class text_info_elementst
499 public:
500 virtual string get_string()
502 string empty;
503 return empty;
505 virtual long get_long()
507 return 0;
510 virtual ~text_info_elementst(){}
513 class text_info_element_stringst : public text_info_elementst
515 public:
516 virtual string get_string()
518 return str;
520 text_info_element_stringst(const string &newstr)
522 str=newstr;
525 protected:
526 string str;
529 class text_info_element_longst : public text_info_elementst
531 public:
532 virtual long get_long()
534 return val;
536 text_info_element_longst(long nval)
538 val=nval;
541 protected:
542 long val;
545 class text_infost
547 public:
548 svector<text_info_elementst *> element;
550 void clean()
552 while(element.size()>0)
554 delete element[0];
555 element.erase(0);
559 string get_string(int e)
561 if(e<0||e>=element.size())
563 string empty;
564 return empty;
566 if(element[e]==NULL)
568 string empty;
569 return empty;
571 return element[e]->get_string();
574 long get_long(int e)
576 if(e<0||e>=element.size())
578 return 0;
580 if(element[e]==NULL)
582 return 0;
584 return element[e]->get_long();
587 ~text_infost()
589 clean();
593 class text_system_file_infost
595 public:
596 long index;
597 string filename;
599 static text_system_file_infost *add_file_info(const string &newf,long newi,char newft)
601 return new text_system_file_infost(newf,newi,newft);
604 void initialize_info();
605 void get_text(text_infost &text);
606 void get_specific_text(text_infost &text,long num);
608 protected:
609 char file_token;
610 long number;
612 text_system_file_infost(const string &newf,long newi,char newft)
614 filename=newf;
615 file_token=newft;
616 index=newi;
617 number=0;
621 class text_systemst
623 public:
624 void register_file_fixed(const string &file_name,int32_t index,char token,char initialize)
626 text_system_file_infost *tsfi=text_system_file_infost::add_file_info(file_name,index,token);
627 if(initialize)tsfi->initialize_info();
628 file_info.push_back(tsfi);
630 void register_file(const string &file_name,int32_t &index,char token,char initialize)
632 int32_t t;
633 for(t=(int32_t)file_info.size()-1;t>=0;t--)
635 if(file_info[t]->filename==file_name)
637 //RESET CALLING INDEX AND BAIL IF THIS FILE IS ALREADY IN THE SYSTEM
638 index=file_info[t]->index;
639 return;
643 text_system_file_infost *tsfi=text_system_file_infost::add_file_info(file_name,index,token);
644 if(initialize)tsfi->initialize_info();
645 file_info.push_back(tsfi);
647 void initialize_system()
649 int32_t t;
650 for(t=(int32_t)file_info.size()-1;t>=0;t--)file_info[t]->initialize_info();
652 void get_text(int32_t index,text_infost &text)
654 int32_t t;
655 for(t=(int32_t)file_info.size()-1;t>=0;t--)
657 if(file_info[t]->index==index)
659 file_info[t]->get_text(text);
660 return;
664 void get_text(const string &file_name,text_infost &text)
666 int32_t t;
667 for(t=(int32_t)file_info.size()-1;t>=0;t--)
669 if(file_info[t]->filename==file_name)
671 file_info[t]->get_text(text);
672 return;
676 void get_specific_text(int32_t index,text_infost &text,int32_t num)
678 int32_t t;
679 for(t=(int32_t)file_info.size()-1;t>=0;t--)
681 if(file_info[t]->index==index)
683 file_info[t]->get_specific_text(text,num);
684 return;
689 ~text_systemst()
691 while(file_info.size()>0)
693 delete file_info[0];
694 file_info.erase(0);
698 protected:
699 svector<text_system_file_infost *> file_info;
702 class curses_text_boxst
704 public:
705 stringvectst text;
707 void add_paragraph(stringvectst &src,int32_t para_width);
708 void add_paragraph(const string &src,int32_t para_width);
710 void read_file(file_compressorst &filecomp,int32_t loadversion)
712 text.read_file(filecomp,loadversion);
714 void write_file(file_compressorst &filecomp)
716 text.write_file(filecomp);
718 void clean()
720 text.clean();
724 #define COPYTEXTUREFLAG_HORFLIP BIT1
725 #define COPYTEXTUREFLAG_VERFLIP BIT2
727 #define ENABLERFLAG_RENDER BIT1
728 #define ENABLERFLAG_MAXFPS BIT2
730 #ifdef WANT_GL
731 // GL texture positions
732 struct gl_texpos {
733 GLfloat left, right, top, bottom;
735 #endif
737 // Covers every allowed permutation of text
738 struct ttf_id {
739 std::string text;
740 unsigned char fg, bg, bold;
742 bool operator< (const ttf_id &other) const {
743 if (fg != other.fg) return fg < other.fg;
744 if (bg != other.bg) return bg < other.bg;
745 if (bold != other.bold) return bold < other.bold;
746 return text < other.text;
749 bool operator== (const ttf_id &other) const {
750 return fg == other.fg && bg == other.bg && bold == other.bold && text == other.text;
754 namespace std {
755 template<> struct hash<ttf_id> {
756 size_t operator()(ttf_id val) const {
757 // Not the ideal hash function, but it'll do. And it's better than GCC's. id? Seriously?
758 return hash<string>()(val.text) + val.fg + (val.bg << 4) + (val.bold << 8);
762 // Being a texture catalog interface, with opengl, sdl and truetype capability
763 class textures
765 friend class enablerst;
766 friend class renderer_opengl;
767 private:
768 vector<SDL_Surface *> raws;
769 bool uploaded;
770 long add_texture(SDL_Surface*);
771 protected:
772 #ifdef WANT_GL
773 GLuint gl_catalog; // texture catalog gennum
774 struct gl_texpos *gl_texpos; // Texture positions in the GL catalog, if any
775 #else
776 uint32_t gl_catalog_abi_dummy;
777 void* gl_texpos_abi_dummy;
778 #endif
779 public:
780 // Initialize state variables
781 textures() {
782 uploaded = false;
783 #ifdef WANT_GL
784 gl_texpos = NULL;
785 #endif
787 ~textures() {
788 for (auto it = raws.cbegin(); it != raws.cend(); ++it)
789 SDL_FreeSurface(*it);
791 int textureCount() {
792 return raws.size();
794 // Upload in-memory textures to the GPU
795 // When textures are uploaded, any alteration to a texture
796 // is automatically reflected in the uploaded copy - eg. it's replaced.
797 // This is very expensive in opengl mode. Don't do it often.
798 void upload_textures();
799 // Also, you really should try to remove uploaded textures before
800 // deleting a window, in case of driver memory leaks.
801 void remove_uploaded_textures();
802 // Returns the most recent texture data
803 SDL_Surface *get_texture_data(long pos);
804 // Clone a texture
805 long clone_texture(long src);
806 // Remove all color, but not transparency
807 void grayscale_texture(long pos);
808 // Loads dimx*dimy textures from a file, assuming all tiles
809 // are equally large and arranged in a grid
810 // Texture positions are saved in row-major order to tex_pos
811 // If convert_magenta is true and the file does not have built-in transparency,
812 // any magenta (255,0,255 RGB) is converted to full transparency
813 // The calculated size of individual tiles is saved to disp_x, disp_y
814 void load_multi_pdim(const string &filename,long *tex_pos,long dimx,long dimy,
815 bool convert_magenta,
816 long *disp_x, long *disp_y);
817 // Loads a single texture from a file, returning the handle
818 long load(const string &filename, bool convert_magenta);
819 // To delete a texture..
820 void delete_texture(long pos);
823 struct tile {
824 int x, y;
825 long tex;
828 #ifdef WANT_GL
829 typedef struct { // Window Creation Info
830 char* title; // Window Title
831 int width; // Width
832 int height; // Height
833 int bitsPerPixel; // Bits Per Pixel
834 BOOL isFullScreen; // FullScreen?
835 } GL_WindowInit; // GL_WindowInit
837 typedef struct { // Contains Information Vital To A Window
838 GL_WindowInit init; // Window Init
839 BOOL isVisible; // Window Visible?
840 } GL_Window; // GL_Window
842 #endif
844 enum zoom_commands { zoom_in, zoom_out, zoom_reset, zoom_fullscreen, zoom_resetgrid };
847 struct texture_fullid {
848 int texpos;
849 float r, g, b;
850 float br, bg, bb;
852 bool operator< (const struct texture_fullid &other) const {
853 if (texpos != other.texpos) return texpos < other.texpos;
854 if (r != other.r) return r < other.r;
855 if (g != other.g) return g < other.g;
856 if (b != other.b) return b < other.b;
857 if (br != other.br) return br < other.br;
858 if (bg != other.bg) return bg < other.bg;
859 return bb < other.bb;
863 typedef int texture_ttfid; // Just the texpos
865 class renderer {
866 void cleanup_arrays();
867 protected:
868 unsigned char *screen;
869 long *screentexpos;
870 char *screentexpos_addcolor;
871 unsigned char *screentexpos_grayscale;
872 unsigned char *screentexpos_cf;
873 unsigned char *screentexpos_cbr;
874 // For partial printing:
875 unsigned char *screen_old;
876 long *screentexpos_old;
877 char *screentexpos_addcolor_old;
878 unsigned char *screentexpos_grayscale_old;
879 unsigned char *screentexpos_cf_old;
880 unsigned char *screentexpos_cbr_old;
882 void gps_allocate(int x, int y);
883 Either<texture_fullid,texture_ttfid> screen_to_texid(int x, int y);
884 public:
885 void display();
886 virtual void update_tile(int x, int y) = 0;
887 virtual void update_all() = 0;
888 virtual void render() = 0;
889 virtual void set_fullscreen() {} // Should read from enabler.is_fullscreen()
890 virtual void zoom(zoom_commands cmd) {};
891 virtual void resize(int w, int h) = 0;
892 virtual void grid_resize(int w, int h) = 0;
893 void swap_arrays();
894 renderer() {
895 screen = NULL;
896 screentexpos = NULL;
897 screentexpos_addcolor = NULL;
898 screentexpos_grayscale = NULL;
899 screentexpos_cf = NULL;
900 screentexpos_cbr = NULL;
901 screen_old = NULL;
902 screentexpos_old = NULL;
903 screentexpos_addcolor_old = NULL;
904 screentexpos_grayscale_old = NULL;
905 screentexpos_cf_old = NULL;
906 screentexpos_cbr_old = NULL;
908 virtual ~renderer() {
909 cleanup_arrays();
911 virtual bool get_mouse_coords(int &x, int &y) = 0;
912 virtual bool uses_opengl() { return false; };
915 class enablerst : public enabler_inputst
917 friend class initst;
918 friend class renderer_2d_base;
919 friend class renderer_2d;
920 friend class renderer_opengl;
921 friend class renderer_curses;
923 bool fullscreen;
924 stack<pair<int,int> > overridden_grid_sizes;
926 class renderer *renderer;
927 void eventLoop_SDL();
928 #ifdef CURSES
929 void eventLoop_ncurses();
930 #endif
932 // Framerate calculations
933 int calculated_fps, calculated_gfps;
934 queue<int> frame_timings, gframe_timings; // Milisecond lengths of the last few frames
935 int frame_sum, gframe_sum;
936 int frame_last, gframe_last; // SDL_GetTick returns
937 void do_update_fps(queue<int> &q, int &sum, int &last, int &calc);
939 public:
940 void clear_fps();
941 private:
942 void update_fps();
943 void update_gfps();
945 // Frame timing calculations
946 float fps, gfps;
947 float fps_per_gfps;
948 Uint32 last_tick;
949 float outstanding_frames, outstanding_gframes;
951 // Async rendering
952 struct async_cmd {
953 enum cmd_t { pause, start, render, inc, set_fps } cmd;
954 int val; // If async_inc, number of extra frames to run. If set_fps, current value of fps.
955 async_cmd() {}
956 async_cmd(cmd_t c) { cmd = c; }
959 struct async_msg {
960 enum msg_t { quit, complete, set_fps, set_gfps, push_resize, pop_resize, reset_textures } msg;
961 union {
962 int fps; // set_fps, set_gfps
963 struct { // push_resize
964 int x, y;
967 async_msg() {}
968 async_msg(msg_t m) { msg = m; }
971 unsigned int async_frames; // Number of frames the async thread has been asked to run
972 bool async_paused;
973 Chan<async_cmd> async_tobox; // Messages to the simulation thread
974 Chan<async_msg> async_frombox; // Messages from the simulation thread, and acknowledgements of those to
975 Chan<zoom_commands> async_zoom; // Zoom commands (from the simulation thread)
976 Chan<void> async_fromcomplete; // Barrier for async_msg requests that require acknowledgement
977 public:
978 Uint32 renderer_threadid;
979 private:
981 void pause_async_loop();
982 void async_wait();
983 void unpause_async_loop() {
984 struct async_cmd cmd;
985 cmd.cmd = async_cmd::start;
986 async_tobox.write(cmd);
989 public:
991 string command_line;
993 float ccolor[16][3]; // The curses-RGB mapping used for non-curses display modes
995 enablerst();
996 unsigned long flag; // ENABLERFLAG_RENDER, ENABLERFLAG_MAXFPS
998 int loop(string cmdline);
999 void async_loop();
1000 void do_frame();
1002 // Framerate interface
1003 void set_fps(int fps);
1004 void set_gfps(int gfps);
1005 int get_fps() { return (int)fps; }
1006 int get_gfps() { return (int)gfps; }
1007 int calculate_fps(); // Calculate the actual provided (G)FPS
1008 int calculate_gfps();
1010 // Mouse interface, such as it is
1011 char mouse_lbut,mouse_rbut,mouse_lbut_down,mouse_rbut_down,mouse_lbut_lift,mouse_rbut_lift;
1012 char tracking_on; // Whether we're tracking the mouse or not
1014 // OpenGL state (wrappers)
1015 class textures textures; // Font/graphics texture catalog
1016 #ifdef WANT_GL
1017 GLsync sync; // Rendering barrier
1018 #else
1019 uint32_t sync_abi_dummy;
1020 #endif
1021 void reset_textures() {
1022 async_frombox.write(async_msg(async_msg::reset_textures));
1024 bool uses_opengl() {
1025 if (!renderer) return false;
1026 return renderer->uses_opengl();
1029 // Grid-size interface
1030 void override_grid_size(int w, int h); // Pick a /particular/ grid-size
1031 void release_grid_size(); // Undoes override_grid_size
1032 void zoom_display(zoom_commands command);
1035 // Window management
1036 bool is_fullscreen() { return fullscreen; }
1037 void toggle_fullscreen() {
1038 fullscreen = !fullscreen;
1039 async_zoom.write(zoom_fullscreen);
1042 // Conversations
1043 text_systemst text_system;
1045 // TOADY: MOVE THESE TO "FRAMERATE INTERFACE"
1046 MVar<int> simticks, gputicks;
1047 Uint32 clock; // An *approximation* of the current time for use in garbage collection thingies, updated every frame or so.
1049 #endif
1051 // Function prototypes for deep-DF calls
1052 char beginroutine();
1053 char mainloop();
1054 void endroutine();
1056 extern enablerst enabler;
1058 #endif //ENABLER_H