refactor OSD code and PCNT stuff
[pcsx_rearmed.git] / frontend / plugin_lib.c
1 /*
2  * (C) notaz, 2010
3  *
4  * This work is licensed under the terms of the GNU GPLv2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdarg.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18 #include "plugin_lib.h"
19 #include "linux/fbdev.h"
20 #include "common/fonts.h"
21 #include "common/input.h"
22 #include "omap.h"
23 #include "pcnt.h"
24 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
25
26 void *pl_fbdev_buf;
27 int keystate;
28 static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp;
29 static int flip_cnt, flips_per_sec, tick_per_sec;
30 extern float fps_cur; // XXX
31
32 static int get_cpu_ticks(void)
33 {
34         static unsigned long last_utime;
35         static int fd;
36         unsigned long utime, ret;
37         char buf[128];
38
39         if (fd == 0)
40                 fd = open("/proc/self/stat", O_RDONLY);
41         lseek(fd, 0, SEEK_SET);
42         buf[0] = 0;
43         read(fd, buf, sizeof(buf));
44         buf[sizeof(buf) - 1] = 0;
45
46         sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu", &utime);
47         ret = utime - last_utime;
48         last_utime = utime;
49         return ret;
50 }
51
52 static void print_fps(void)
53 {
54         if (pl_fbdev_bpp == 16)
55                 pl_text_out16(2, pl_fbdev_h - 10, "%2d %4.1f", flips_per_sec, fps_cur);
56 }
57
58 static void print_cpu_usage(void)
59 {
60         if (pl_fbdev_bpp == 16)
61                 pl_text_out16(pl_fbdev_w - 28, pl_fbdev_h - 10, "%3d", tick_per_sec);
62 }
63
64 int pl_fbdev_init(void)
65 {
66         pl_fbdev_buf = vout_fbdev_flip(layer_fb);
67         return 0;
68 }
69
70 int pl_fbdev_set_mode(int w, int h, int bpp)
71 {
72         void *ret;
73
74         if (w == pl_fbdev_w && h == pl_fbdev_h && bpp == pl_fbdev_bpp)
75                 return 0;
76
77         pl_fbdev_w = w;
78         pl_fbdev_h = h;
79         pl_fbdev_bpp = bpp;
80
81         vout_fbdev_clear(layer_fb);
82         ret = vout_fbdev_resize(layer_fb, w, h, bpp, 0, 0, 0, 0, 3);
83         if (ret == NULL)
84                 fprintf(stderr, "failed to set mode\n");
85         else
86                 pl_fbdev_buf = ret;
87
88         return (ret != NULL) ? 0 : -1;
89 }
90
91 void pl_fbdev_flip(void)
92 {
93         /* doing input here because the pad is polled
94          * thousands of times for some reason */
95         int actions[IN_BINDTYPE_COUNT] = { 0, };
96
97         in_update(actions);
98         if (actions[IN_BINDTYPE_EMU] & PEV_MENU)
99                 stop = 1;
100         keystate = actions[IN_BINDTYPE_PLAYER12];
101
102         flip_cnt++;
103         print_fps();
104         print_cpu_usage();
105
106         // let's flip now
107         pl_fbdev_buf = vout_fbdev_flip(layer_fb);
108 }
109
110 void pl_fbdev_finish(void)
111 {
112 }
113
114 /* called on every vsync */
115 void pl_frame_limit(void)
116 {
117         extern void CheckFrameRate(void);
118         static int oldsec;
119         struct timeval tv;
120
121         pcnt_end(PCNT_ALL);
122         gettimeofday(&tv, 0);
123
124         if (tv.tv_sec != oldsec) {
125                 flips_per_sec = flip_cnt;
126                 flip_cnt = 0;
127                 tick_per_sec = get_cpu_ticks();
128                 oldsec = tv.tv_sec;
129         }
130 #ifdef PCNT
131         static int ya_vsync_count;
132         if (++ya_vsync_count == PCNT_FRAMES) {
133                 pcnt_print(fps_cur);
134                 ya_vsync_count = 0;
135         }
136 #endif
137
138         CheckFrameRate();
139
140         pcnt_start(PCNT_ALL);
141 }
142
143 static void pl_text_out16_(int x, int y, const char *text)
144 {
145         int i, l, len = strlen(text), w = pl_fbdev_w;
146         unsigned short *screen = (unsigned short *)pl_fbdev_buf + x + y * w;
147         unsigned short val = 0xffff;
148
149         for (i = 0; i < len; i++, screen += 8)
150         {
151                 for (l = 0; l < 8; l++)
152                 {
153                         unsigned char fd = fontdata8x8[text[i] * 8 + l];
154                         unsigned short *s = screen + l * w;
155                         if (fd&0x80) s[0] = val;
156                         if (fd&0x40) s[1] = val;
157                         if (fd&0x20) s[2] = val;
158                         if (fd&0x10) s[3] = val;
159                         if (fd&0x08) s[4] = val;
160                         if (fd&0x04) s[5] = val;
161                         if (fd&0x02) s[6] = val;
162                         if (fd&0x01) s[7] = val;
163                 }
164         }
165 }
166
167 void pl_text_out16(int x, int y, const char *texto, ...)
168 {
169         va_list args;
170         char    buffer[256];
171
172         va_start(args, texto);
173         vsnprintf(buffer, sizeof(buffer), texto, args);
174         va_end(args);
175
176         pl_text_out16_(x, y, buffer);
177 }
178